在Java中与boolean常量进行显式比较是否不好(例如,如果(b == false))?


73

写不好吗:

if (b == false) //...

while (b != true) //...

是不是总是更好,而不是写:

if (!b) //...

while (!b) //...

大概在性能上没有区别(或存在什么区别?),但是您如何权衡两者之间的明确性,简洁性,清晰度,可读性等?

更新资料

为了限制主观性,我还要感谢权威编码风格指南中的所有引号,这些引号始终是更可取的或在何时使用。


注意:变量名称b仅用作示例alafoobar


9
出于可读性原因,我个人喜欢将文字与文字进行比较-在高分辨率(且年龄增加)下,感叹号往往被许多字母“吸收”。
乌里(Uri)

@Uri:!如果确实存在问题,那么足够好的IDE应该能够使您脱颖而出。
polygenelubricants 2010年

55
if (b == false == true == true) {您要确定。
Tom Hawtin-大头钉

2
@Triynko,通常这种事情已经过优化,所以没关系,如果不是的话,也不会引起明显的差异。
Nacht'3

8
事实是,人们只使用“ == true”之类的东西,因为他们实际上并没有考虑过这一点,并且在向他们指出时,他们声称“可读性”可以挽回面子。
Nacht'4

Answers:


67

不一定坏,只是多余的。同样,实际的变量名也很重要。例如if (userIsAllowedToLogin),我更希望以上if (b),甚至更差if (flag)

至于性能问题,编译器会以任何方式对其进行优化。

更新:关于权威资料,我在《Sun Coding Conventions》中找不到明确的内容,但是至少Checkstyle有一个SimplifyBooleanExpression模块会对此发出警告。


7
+1用于推荐长的描述性变量名。但是,我认为“ if(userIsAllowedToLogin())”优于“ if(userIsAllowedToLogin()== true)”,因为前者更具可读性。
Michael Aaron Safyan

@Michael,你忘记了!吗?
托尔比约恩Ravn的安徒生

我宁愿if( canAuthenticate() )还是if( isAuthorized() )。我觉得userIsAllowedToLogin模棱两可。这是否意味着用户可以查看登录页面(例如,未禁止IP地址),还是意味着用户已通过身份验证(例如,正确的名称和密码)?
Dave Jarvis 2010年

1
@戴夫:这只是一个夸张的例子。只要变量名很容易解释即可。
BalusC 2010年

4
@BalusC:我知道;这是宠物的烦恼。长的方法名称(例如isCurrentUserLoggedInAsRole)有时是更大问题的征兆:方法放错了位置。(例如,User班级应该知道其分配的角色:user.isAssigned( role )。)
Dave Jarvis 2010年

48

您不应该使用第一种样式。我见过人们使用:

  • if ( b == true )
  • if ( b == false )

我个人觉得很难阅读,但是可以通过。但是,这种风格的一个大问题是它导致了您所展示的令人难以置信的违反直觉的例子:

  • if ( b != true )
  • if ( b != false )

读者需要花更多的精力来确定作者的意图。就我个人而言,我发现将对真或假的显式比较包括在内是多余的,因此很难阅读,但这就是我。


8
+1这是该主题中的另一个最佳答案。实际上,它们确实(有点)难以快速解释至少对于我来说。
BalusC 2010年

35

这完全是一个品味问题。

就个人而言,我发现它的可读性比我if (!a) {低(编辑:对我而言),因此在以后维护代码时更容易出错,并且我已经转换为使用后一种形式。if (a == false) {

基本上,我不喜欢为逻辑运算而不是单词(C与Pascal)选择符号,因为对 a = 10 and not b = 20而言a == 10 && !(b==20),它比容易阅读,但这就是Java中的用法。

任何赞成“ == false”的人都赞成“!” 显然,从来没有盯着代码太久而错过了感叹号。是的,您会遇到代码盲的情况。


3
我同意,从可读性的角度来看,与(!)相比,我也更喜欢使用== false -在维护其他人的代码时,正如您所说的那样,代码盲目性确实存在并且确实会发生。if(K){}或if(!K){}有时,您可能花了很长时间才能弄清为什么某些东西不起作用,然后找出!在这种情况下。
哈拉格2015年

解决此问题的最佳方法是使布尔表达式测试为true而不是false,并相应地对if-then-blocks进行排序。如果true块为空,这可能看起来很奇怪。
托尔比约恩Ravn的安徒生

25

您不应该使用第一种样式的主要原因是,这两种都是有效的:

if (b = false) //...

while (b = true) //...

也就是说,如果您不小心遗漏了一个字符,那么您将创建一个分配而不是一个比较。赋值表达式的计算结果为已分配的值,所以第一个语句的上方将值falseb和计算结果为false。第二个值分配trueb,因此true无论您b在循环内进行什么操作,它始终求值为。


8
我不会说“压倒一切”的原因。除非您有15年的旅行时间,否则编译器会警告您输入错误。
约翰·库格曼

1
约翰可能是您的IDE。请注意,这在C#中无效……刺戳!
斯蒂芬·斯文森

1
是的,IDE和样式检查器将警告您这种情况。尽管默认情况下它不会警告您,但如果命令行编译器也能够检测到它,我也不会感到惊讶。我的观点是,这不仅仅是样式选择。
艾伦·摩尔

3
@StephenSwensen,它在C#中有效,但是会生成警告。Assignment in conditional expression is always constant; did you mean to use == instead of = ?
user247702 2012年

2
防止这种情况的一种简单方法是将常数(lhs)与变量(rhs)进行比较。这样while (true == loggedIn)。这样,它将引发编译时错误而不是运行时错误。
亚当·布里恩德

11

除了初学者编写的代码外,我从未见过。总是后者,而且我认为没有人对此感到困惑。另一方面,我认为

int x;
...
if(x) //...

if(x != 0) //...

更值得商bat,在那种情况下,我确实更喜欢第二种


4
@ Michael,Java不会像在C ++中那样将int隐式转换为boolean,否则同意100%。前者是草率的新手语法,后者是首选。
Michael Aaron Safyan'4

4
哦,我什至没有意识到我们在谈论Java :)
Michael Mrozek 2010年

1
它在标签中,但现在在标题中也提到了。抱歉造成混乱。
polygenelubricants 2010年

1
好了,现在您知道,由于这篇文章,一些有经验的程序员写了“ == false”-而不仅仅是“初学者”,并且您可以清楚地了解他们的原因,如此处多次答复所述。(嗯……那是一个潜意识的主宰者吗?“我喜欢这个,而且我见过的唯一不同意我的偏爱的人只是'初学者'。”)
M.Bearden

@ M.Bearden认真吗?我只是想说的是,我个人几乎从未见过经验丰富的程序员可以直接与trueor进行比较false,而当我在大学攻读助教时,我总是会从新手身上看到它,而他们根本没有意识到这是多余的。这并不意味着如果您做的不好,那是不常见的。从五年前开始,您就冒犯了很多言论,没有针对任何人。根据您的喜好编写代码
Michael Mrozek 2014年

7

恕我直言,我认为,如果仅使bool变量名称带有"Is",这是不言而喻的,更有意义,然后,您可以删除带有true或的显式比较false

例:

isEdited  // use IsEdited in case of property names
isAuthorized // use IsAuthorized in case of property names

等等


2
的约定是isEdited,不IsEdited(后者将是一个类)
托尔比约恩Ravn的安德森

6

我更喜欢第一个,因为它更清晰。机器可以很好地阅读,但是我尝试编写代码供其他阅读,而不仅仅是机器。


有趣的是,如此多的人似乎不同意我的意见-此答案目前有6个赞成票和3个反对票。也许这解释了我被要求进行救助的所有“泥泞之球”项目……
极客头

3

我更喜欢长距离的方法,但是我比较使用==而不是!=99%的时间。

我知道这个问题是关于Java的,但是我经常在各种语言之间切换C#,例如,== false在处理nullable bool类型时,与(比较)可以比较有用。所以我有比较使用true或不false使用==运算符的习惯。

我做这些:

if(isSomething == false) 要么 if(isSomething == true)

但我讨厌这些:

if(isSomething != false) 要么 if(isSomething != true)

出于明显的可读性原因!

只要您保持代码可读性,就没有关系。


2

就个人而言,我将重构代码,以便不使用负面测试。例如。

if (b == false) {
   // false
} else {
   // true
}

要么

boolean b = false;
while(b == false) {
  if (condition)
      b = true;
}

恕我直言,在90%的情况下,代码可以重构,因此不需要否定测试。


但不要走太远。信不信由你,我已经看过这样的代码:if(a); 否则doSomething();
Axel 2010年

在这种情况下,我希望(!a)doSomething(); 但是您可能会发现您可以更改代码,以便“ b”存储true(而不是false)和false(而不是true),并且不需要取反。恕我直言,如果(a)在一个地方,(!a)在不相关的代码块中,则很少需要。
彼得·劳瑞


1

通常的准则是永远不要测试布尔值。有人认为,额外的冗长性增加了清晰度。添加的代码可能会对某些人有所帮助,但是每个读者都需要阅读更多的代码。

今天早上,我花了1/2个小时才找到一个错误。该代码是

    if ( !strcmp(runway_in_use,"CLOSED") == IPAS_FALSE)
      printf(" ACTIVE    FALSE \n");   else
      printf(" ACTIVE    TRUE \n");

如果使用常规惯例进行编码,我会发现它错了的速度要快得多:

    if (strcmp(runway_in_use, "CLOSED"))
      printf(" ACTIVE    FALSE \n");   else
      printf(" ACTIVE    TRUE \n");

我认为该条件中存在更大的可读性问题。看一下strcmp。并非完全毫不费力的IMO。
Preza8

1

这是我对StackOverflow的第一个答案,所以很好。...最近在重构时,我注意到2个代码块几乎具有完全相同的代码,但其中一个使用了

for (Alert alert : alerts) {
    Long currentId = alert.getUserId();

    if (vipList.contains(currentId)) {
        customersToNotify.add(alert);

        if (customersToNotify.size() == maxAlerts) {
            break;
        }
    }
}

另一个有

for (Alert alert : alerts) {
    Long currentId = alert.getUserId();

    if (!vipList.contains(currentId)) {
        customersToNotify.add(alert);

        if (customersToNotify.size() == maxAlerts) {
            break;
        }
    }
}

因此在这种情况下,有必要创建一种方法来处理这样的两种情况,并使用boolean == condition翻转含义

private void appendCustomersToNotify(List<Alert> alerts
        List<Alert> customersToNotify, List<Long> vipList, boolean vip){

    for (Alert alert : alerts) {
        Long currentId = alertItem.getUserId();

        if (vip == vipList.contains(currentId)) {
            customersToNotify.add(alertItem);

            if (customersToNotify.size() == maxAlerts) {
                break;
            }
        }
    }
}

0

我会说这很糟糕。

while (!b) {
    // do something 
}

阅读比

while (b != true) {
    // do something 
}

0

不赞成使用第一个(b == false)的原因之一是,初学者通常根本没有意识到第二个选择(!b)完全可行。因此,使用第一种形式可能会误解布尔表达式和布尔变量。这样,使用第二种形式已成为一种sjiboleth:当某人写下此内容时,他/她可能知道发生了什么。

我认为,这已导致差异比实际更重要。


0

虽然两者都是有效的,但对我而言,第一种感觉就像是类型错误。

对我来说b == false好像是错误的(i == 0) == false。就像:是吗?

布尔值不是具有2个可能值的枚举。您不比较它们。布尔是谓词,表示某些事实。它们有像特定运营商&|^!

要反转表达式的真相,请使用运算符“!”,并将其发音为“ not”。

正确命名后,它就变得自然了:!isEmpty对我来说,可读性很强。
虽然isEmpty == false读到诸如“它为空是错误的”之类的信息,但我需要更多时间来处理。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.