Java null检查为什么使用==代替.equals()

Java null check why use == instead of .equals()

在Java中,我被告知在执行null检查时应使用==而不是.equals()。 是什么原因呢?


他们是两个完全不同的东西。 ==比较变量包含的对象引用(如果有)。 .equals()根据两个对象的约定检查两个对象是否相等。根据它们的契约,两个不同的对象实例完全有可能"相等"。然后有一个次要细节,因为equals是一种方法,如果尝试在null引用上调用它,则会得到一个NullPointerException

例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
class Foo {
    private int data;

    Foo(int d) {
        this.data = d;
    }

    @Override
    public boolean equals(Object other) {
        if (other == null || other.getClass() != this.getClass()) {
           return false;
        }
        return ((Foo)other).data == this.data;
    }

    /* In a real class, you'd override `hashCode` here as well */
}

Foo f1 = new Foo(5);
Foo f2 = new Foo(5);
System.out.println(f1 == f2);
// outputs false, they're distinct object instances

System.out.println(f1.equals(f2));
// outputs true, they're"equal" according to their definition

Foo f3 = null;
System.out.println(f3 == null);
// outputs true, `f3` doesn't have any object reference assigned to it

System.out.println(f3.equals(null));
// Throws a NullPointerException, you can't dereference `f3`, it doesn't refer to anything

System.out.println(f1.equals(f3));
// Outputs false, since `f1` is a valid instance but `f3` is null,
// so one of the first checks inside the `Foo#equals` method will
// disallow the equality because it sees that `other` == null


如果在null上调用.equals(),则将得到NullPointerException

因此,始终建议在适用的地方调用方法之前检查无效性

1
2
3
if(str!=null && str.equals("hi")){
 //str contains hi
}

另请参阅

  • Java中的equal-between-equals-和==


除了接受的答案(https://stackoverflow.com/a/4501084/6276704):

从Java 1.7开始,如果要比较两个可能为null的对象,我建议使用此函数:

1
Objects.equals(onePossibleNull, twoPossibleNull)

java.util.Objects

This class consists of static utility methods for operating on
objects. These utilities include null-safe or null-tolerant methods
for computing the hash code of an object, returning a string for an
object, and comparing two objects.

Since:
1.7


在Java中,0或null是简单类型,而不是对象。

equals()方法不是为简单类型构建的。简单类型可以与==匹配。


1
foo.equals(null)

如果foo为null会怎样?

您得到一个NullPointerException。


如果我们使用=> .equals方法

1
2
3
if(obj.equals(null))  

// Which mean null.equals(null) when obj will be null.

当您的obj为null时,它将引发Null Point Exception。

所以我们应该使用==

1
if(obj == null)

它将比较参考。


根据消息来源,默认方法实现使用什么都没有关系:

1
2
3
public boolean equals(Object object) {
    return this == object;
}

但是您不能确定自定义类中的equals


如果尝试在空对象引用上调用equals,则将引发空指针异常。


如果Object变量为null,则无法对其调用equals()方法,因此,对对象引用null进行检查是正确的。


这是使用org.jsonstr != nullstr.equals(null)的示例

1
2
3
4
5
 JSONObject jsonObj = new JSONObject("{field :null}");
 Object field = jsonObj.get("field");
 System.out.println(field != null);        // => true
 System.out.println( field.equals(null)); //=> true
 System.out.println( field.getClass());  // => org.json.JSONObject$Null

编辑:
这是org.json.JSONObject $ Null类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/**
 * JSONObject.NULL is equivalent to the value that JavaScript calls null,
 * whilst Java's null is equivalent to the value that JavaScript calls
 * undefined.
 */

private static final class Null {

    /**
     * A Null object is equal to the null value and to itself.
     *
     * @param object
     *            An object to test for nullness.
     * @return true if the object parameter is the JSONObject.NULL object or
     *         null.
     */

    @Override
    public boolean equals(Object object) {
        return object == null || object == this;
    }  
}


因为equal是从Object类派生的函数,所以该函数比较该类的项。如果将它与null一起使用,它将返回false,原因是类的内容不为null。另外,==比较对对象的引用。


我昨晚遇到过这种情况。
我认为这很简单:

Don't exist equals() method for null
So, you can not invoke an inexistent method if you don't have
-->>> That is reason for why we use == to check null


因此,我永远不会感到困惑,并且避免使用此解决方案出现问题:

1
2
3
if(str.trim().length() <=0 ) {
   // is null !
}


你总是可以做

1
if (str == null || str.equals(null))

这将首先检查对象引用,然后在引用不为null的情况下检查对象本身。