Java null 检查为什么使用 == 而不是 .equals()

发布于 2024-10-08 19:11:42 字数 60 浏览 2 评论 0原文

在 Java 中,我被告知在进行 null 检查时应该使用 == 而不是 .equals()。其原因何在?

In Java I am told that when doing a null check one should use == instead of .equals(). What are the reasons for this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(16

傻比既视感 2024-10-15 19:11:42

它们是完全不同的两个东西。 == 比较变量包含的对象引用(如果有)。 .equals() 根据两个对象对于相等含义的约定来检查它们是否相等。根据契约,两个不同的对象实例完全有可能“相等”。还有一个小细节,由于 equals 是一个方法,如果您尝试在 null 引用上调用它,您将得到一个 NullPointerException

例如:

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

They're two completely different things. == compares the object reference, if any, contained by a variable. .equals() checks to see if two objects are equal according to their contract for what equality means. It's entirely possible for two distinct object instances to be "equal" according to their contract. And then there's the minor detail that since equals is a method, if you try to invoke it on a null reference, you'll get a NullPointerException.

For instance:

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
不羁少年 2024-10-15 19:11:42

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

从 Java 1.7 开始,如果你想比较两个可能为空的对象,我推荐这个函数:

Objects.equals(onePossibleNull, twoPossibleNull)

java.util.Object

此类由静态实用方法组成,用于操作
对象。这些实用程序包括 null 安全或 null 容忍方法
用于计算对象的哈希码,返回一个字符串
对象,并比较两个对象。

自:
1.7

In addition to the accepted answer (https://stackoverflow.com/a/4501084/6276704):

Since Java 1.7, if you want to compare two Objects which might be null, I recommend this function:

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

弥枳 2024-10-15 19:11:42

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

因此,在调用方法之前,无论它适用于什么地方,总是建议检查 nullity

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

<强>另请参阅

if you invoke .equals() on null you will get NullPointerException

So it is always advisble to check nullity before invoking method where ever it applies

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

Also See

嘿嘿嘿 2024-10-15 19:11:42

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

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

In Java 0 or null are simple types and not objects.

The method equals() is not built for simple types. Simple types can be matched with ==.

欢烬 2024-10-15 19:11:42

Object.equals 是 null 安全的,但请注意,如果两个对象为 null,object.equals 将返回 true,因此在使用 object.equals 之前,请务必检查要比较的对象是否不为 null(或持有 null 值)比较。

String firstname = null;
String lastname = null;

if(Objects.equals(firstname, lastname)){
    System.out.println("equal!");
} else {
    System.out.println("not equal!");
}

上面的示例片段将返回 equal!

Object.equals is null safe, however be aware that if two objects are null, object.equals will return true so be sure to check that the objects you are comparing aren't null (or hold null values) before using object.equals for comparison.

String firstname = null;
String lastname = null;

if(Objects.equals(firstname, lastname)){
    System.out.println("equal!");
} else {
    System.out.println("not equal!");
}

Example snippet above will return equal!

我是有多爱你 2024-10-15 19:11:42
foo.equals(null)

如果 foo 为空会发生什么?

你会得到一个 NullPointerException。

foo.equals(null)

What happens if foo is null?

You get a NullPointerException.

在你怀里撒娇 2024-10-15 19:11:42

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

If an Object variable is null, one cannot call an equals() method upon it, thus an object reference check of null is proper.

命比纸薄 2024-10-15 19:11:42

如果尝试对空对象引用调用 equals,则会抛出空指针异常。

If you try calling equals on a null object reference, then you'll get a null pointer exception thrown.

薆情海 2024-10-15 19:11:42

根据 来源 使用什么并不重要对于默认方法实现:

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

但是您无法确定自定义类中的 equals

According to sources it doesn't matter what to use for default method implementation:

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

But you can't be sure about equals in custom class.

挽梦忆笙歌 2024-10-15 19:11:42

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

if(obj.equals(null))  

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

当你的 obj 为 null 时,它会抛出 Null Point Exception。

所以我们应该使用 ==

if(obj == null)

来比较引用。

If we use=> .equals method

if(obj.equals(null))  

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

When your obj will be null it will throw Null Point Exception.

so we should use ==

if(obj == null)

it will compare the references.

○愚か者の日 2024-10-15 19:11:42

这是一个示例,其中使用 org.jsonstr != nullstr.equals(null)

 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班级:

/**
 * 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;
    }  
}

here is an example where str != null but str.equals(null) when using org.json

 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

EDIT:
here is the org.json.JSONObject$Null class:

/**
 * 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;
    }  
}
旧故 2024-10-15 19:11:42

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

Because equal is a function derived from Object class, this function compares items of the class. if you use it with null it will return false cause cause class content is not null. In addition == compares reference to an object.

一桥轻雨一伞开 2024-10-15 19:11:42

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

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

So I never get confused and avoid problems with this solution:

if(str.trim().length() <=0 ) {
   // is null !
}
青春有你 2024-10-15 19:11:42

我昨晚就遇到过这个案例。

我简单地确定:

对于 null 不存在 equals() 方法

因此,如果您没有,则无法调用不存在的方法

-->>>>这就是为什么我们使用 == 来检查 null

I have encountered this case last night.

I determine that simply that:

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

樱娆 2024-10-15 19:11:42

你的代码违反了德墨忒尔定律。这就是为什么最好重构设计本身。作为一种解决方法,您可以使用

   obj = Optional.ofNullable(object1)
    .map(o -> o.getIdObject11())
    .map(o -> o.getIdObject111())
    .map(o -> o.getDescription())
    .orElse("")

上面的Optional来检查对象的层次结构,因此

Optional.ofNullable(object1) 

如果您只有一个对象要检查,则

只需使用希望这会有所帮助!!!!

You code breaks Demeter's law. That's why it's better to refactor the design itself. As a workaround, you can use Optional

   obj = Optional.ofNullable(object1)
    .map(o -> o.getIdObject11())
    .map(o -> o.getIdObject111())
    .map(o -> o.getDescription())
    .orElse("")

above is to check to hierarchy of a object so simply use

Optional.ofNullable(object1) 

if you have only one object to check

Hope this helps !!!!

甜心 2024-10-15 19:11:42

你总是可以这样做,

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

这将首先检查对象引用,然后检查对象本身,前提是引用不为空。

You could always do

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

This will first check the object reference and then check the object itself providing the reference isnt null.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文