object==null 或者 null==object?

114

我听说使用null == objectobject == null更好。

例如:

void m1(Object obj ) {
   if(null == obj)  // Is this better than object == null ? Why ?
       return ;
   // Else blah blah
}

这是有原因的,而不是另一个神话吗? 谢谢帮助。


5
"null == object"被称为Yoda条件 - Ciro Santilli OurBigBook.com
11个回答

160

这可能是从C语言学来的一种习惯,为了避免这种错别字(单个=代替双个==):

if (object = null) {

在Java中,将常量放在==的左侧惯例并不实用,因为Java要求if语句中的表达式评估为boolean值,因此无论你如何放置参数,除非常量是一个boolean,否则都会导致编译错误。(如果是布尔值,你也不应该使用==...)


38

正如其他人所说,这是从C语言中学到的一种习惯,以避免打错字 - 尽管即使在C语言中,我也希望高警告级别下的合理编译器能给出警告。正如Chandru所说,在Java中以这种方式与null进行比较只有当您使用Boolean类型变量(而在示例代码中您没有)时才会导致问题。我认为这是一个相当罕见的情况,并且不值得改变您在其他地方编写代码的方式。(即使在这种情况下,我也不会费心反转运算符;如果我清晰地考虑反转它们,我肯定能数清楚等号)。

还没有提到的是,许多人(包括我自己)发现if (variable == constant)形式更易读 - 这是一种更自然的表达方式。这是一个不盲目地从C语言复制约定的原因。您应该始终在假设一个环境中有用的东西在另一个环境中也有用之前质疑实践(就像您在这里做的一样 :))。


30

除非对象的类型是Boolean,否则在Java(1.5+)中这并没有太大的价值。 在这种情况下,这仍然很方便。

如果对象是Boolean,那么在Java 1.5+中if (object = null)不会导致编译失败,但会在运行时引发NullPointerException


2
对于非布尔类型,代码将无法编译,因为表达式“object = null”的类型不是布尔类型。由于自动装箱,对于布尔类型,它将编译。 - Chandra Sekar

10

这也密切相关于:

if ("foo".equals(bar)) {

如果你不想处理NPE,这将非常方便:

if (bar!=null && bar.equals("foo")) {

9
在Java中没有很好的理由。
其他几个答案声称,这是因为你可能会意外地将其赋值而不是相等。但在Java中,你必须在if语句中使用布尔型变量,所以这样写:
if (o = null)

无法编译。

在Java中,唯一会影响到这个问题的情况是变量为布尔类型:

int m1(boolean x)
{
    if (x = true)  // oops, assignment instead of equality

5

这个技巧旨在防止类似v = null的拼写错误。

但是,在Java中,只有布尔表达式可以作为if()条件,因此这个技巧并没有太多意义,编译器会发现这些拼写错误。

然而,对于C/C++代码来说,这仍然是一种有价值的技巧。


3

这是针对那些倾向于将常量放在左侧的人。

在大多数情况下,将常量放在左侧会防止抛出NullPointerException(或者有其他空值检查)。例如,String方法equals也会进行空值检查。将常量放在左侧,将使您避免编写额外的检查。否则,将在后面以另一种方式执行。将null值放在左侧只是为了保持一致。

例如:

 String b = null;
 "constant".equals(b);  // result to false
 b.equals("constant");  // NullPointerException
 b != null && b.equals("constant");  // result to false

3
与下面的代码进行比较:
    String pingResult = "asd";
    long s = System.nanoTime ( );
    if ( null != pingResult )
    {
        System.out.println ( "null != pingResult" );
    }
    long e = System.nanoTime ( );
    System.out.println ( e - s );

    long s1 = System.nanoTime ( );
    if ( pingResult != null )
    {
        System.out.println ( "pingResult != null" );
    }
    long e1 = System.nanoTime ( );
    System.out.println ( e1 - s1 );

输出(多次执行后):

null != pingResult
325737
pingResult != null
47027

因此,pingResult != null 是胜利者。

不知道如果你改变了检查的顺序是否会有相同的结果。不知道这是否在所有版本的Java和所有平台上都是一致的。 - Kirby

3
出于与C语言相同的原因,赋值是一个表达式,所以你把字面量放在左边,这样如果你意外使用“=”而不是“==”时,就不会覆盖它。

1
不行,Java编译器将会捕获那种类型的拼写错误,以任何顺序您喜欢。 - vava

2
"最初的回答":这是一种用不同方式编写的Yoda条件语句。
在Java中,它可以这样写:
String myString = null;
if (myString.equals("foobar")) { /* ... */ } //Will give u null pointer

yoda condition

String myString = null;
if ("foobar".equals(myString)) { /* ... */ } // will be false 

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接