如果比较的两个对象都为null,那么equals方法应返回什么?

时间:2013-10-07 19:32:34

标签: java null equals

我使用Eclipse自动工具为人物Object实现equals方法。 如果两个人反对,p1p2nullp1.equals(p2)应该返回什么? 当前的实现提供了我的Eclipse返回True。但是,我尝试比较null字符串对象,并抛出NullPointerException.这是代码。另外,我想知道为什么不同运行的代码会产生不同的结果。我粘贴了

下面的输出
class Parent2 {
private String name;
private int id;
public static int count = 0;

public Parent2(String name, int id) {
    this.name = name;
    this.id = id;
    if (this.getClass() == Parent2.class)
        count++;
}

@Override
public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = prime * result + id;
    result = prime * result + ((name == null) ? 0 : name.hashCode());
    return result;
}

@Override
public boolean equals(Object obj) {
    if (this == obj)
        return true;
    if (obj == null)
        return false;
    if (getClass() != obj.getClass())
        return false;
    Parent2 other = (Parent2) obj;
    if (id != other.id)
        return false;
    if (name == null) {
        if (other.name != null) {
            System.out.println("here2");
            return false;
        }
    } else if (!name.equals(other.name)) {
        System.out.println("here");
        return false;
    }
    return true;


}

}

public class App {
    public static void main(String[] args) {
        Parent2 par = new Parent2("aa", 5);
        Parent2 par2 = new Parent2(null, 5);
        Parent2 par3 = new Parent2(null, 5);

    System.out.println(par.equals(par2));
    System.out.println(par2.equals(par));
    System.out.println(par3.equals(par2));

    System.out.println("----------------------------------------");

    String str = null;
    String str2 = null;

    System.out.println(str.equals(str2));
    System.out.println(str + "; " + str2);
}

}

每次执行的输出都不同,这里有几个:

here
false
here2Exception in thread "main" java.lang.NullPointerException
    at RoundTwo.App.main(App.java:64)

false
true
----------------------------------------

OUTPUT2:

here
Exception in thread "main" java.lang.NullPointerException
    at RoundTwo.App.main(App.java:64)
false
here2
false
true
----------------------------------------

ouput3:

here
false
here2
false
true
Exception in thread "main" java.lang.NullPointerException
    at RoundTwo.App.main(App.java:64)
----------------------------------------

ouput4:

here
falseException in thread "main" java.lang.NullPointerException
    at RoundTwo.App.main(App.java:64)

here2
false
true
----------------------------------------

ouput5:

here
false
here2
false
true
----------------------------------------
Exception in thread "main" java.lang.NullPointerException
    at RoundTwo.App.main(App.java:64)

仅执行最后一次输出,执行抛出string equals的代码的NullpointerException部分

感谢您提供帮助

5 个答案:

答案 0 :(得分:4)

通常:如果控制流已经在实例方法中,则调用该方法的实例不为null。

因此,在equals方法中,两个对象都不能是null,因为控件流已经在实例方法中。引用this 永远不会null。 (在静态上下文中,它不可用,并且使用它会导致编译器错误)

然而,您的直接问题是,如果要执行相等性检查的对象为空,执行将甚至不输入您的equals方法 - 您无法调用null对象上的实例方法:获得NullPointerException

涉及空值的其他案例

Comparator实例但是应该处理这种情况:在这种情况下,它应该返回0

控制台输出的奇怪行为

控制台上消息的顺序不同,因为您要写入两个不同的流:System.errSystem.out。在这种情况下,不能保证打印消息的顺序与它们写入的顺序相同......

答案 1 :(得分:3)

如果P1和P2均为空,则应返回NullPointerException,因为您无法在NULL上调用equals方法。

答案 2 :(得分:3)

正如其他人所说,对null变量执行任何操作都会引发NullPointerException。我想这是你问题中的主要问题:

  

只有最后一个输出,执行字符串等于抛出NullpointerException的代码的一部分

这是错误的。您在每次执行时看到不同输出的事实是因为System.out.println()System.out PrintStream上写入,而RuntimeException s在NullPointerException上写入System.err } PrintStream。两个流都在同一个控制台上结束写入,但不保证他们将刷新内容的时间。如果要查看其行为方式,请使用单个缓冲区打印所有内容,包括异常,例如使用记录器而不是普通System.out调用。基本样本将是:

public class App {
    public static void main(String[] args) {

    try {
        Parent2 par = new Parent2("aa", 5);
        Parent2 par2 = new Parent2(null, 5);
        Parent2 par3 = new Parent2(null, 5);

    System.out.println(par.equals(par2));
    System.out.println(par2.equals(par));
    System.out.println(par3.equals(par2));

    System.out.println("----------------------------------------");

    String str = null;
    String str2 = null;

    System.out.println(str.equals(str2));
    System.out.println(str + "; " + str2);
    } catch (Exception e) {
        //this will do the "trick"
        e.printStacktrace(System.out);
    }
    }
}

现在,每次执行您的应用程序时,您都会得到一个结果:

here
false
here2
false
true
----------------------------------------
Exception in thread "main" java.lang.NullPointerException
    at RoundTwo.App.main(App.java:64)

  

但是,我尝试比较null字符串对象,并抛出NullPointerException。

对您的p1p2对象执行相同的操作,您会看到NullPointerException出现。从上面的代码:

public class App {
    public static void main(String[] args) {

    try {
        Parent2 par = new Parent2("aa", 5);
        Parent2 par2 = new Parent2(null, 5);
        Parent2 par3 = new Parent2(null, 5);
    par = null;
    par2 = null;
    System.out.println(par.equals(par2)); // <-- NPE here
    System.out.println(par2.equals(par));
    System.out.println(par3.equals(par2));

    System.out.println("----------------------------------------");

    String str = null;
    String str2 = null;

    System.out.println(str.equals(str2));
    System.out.println(str + "; " + str2);
    } catch (Exception e) {
        //this will do the "trick"
        e.printStacktrace(System.out);
    }
    }
}

答案 3 :(得分:1)

您不需要在方法中考虑这种情况。如果this自动为null NullPointerException,则无法覆盖此行为。

使用方法重载时,将在o1.equals(o2)上调用的确切方法取决于{em>运行时类型o1。由于null没有运行时类型(没有对象),因此没有可以调用的方法。因此,总是抛出NullPointerException

答案 4 :(得分:1)

  
    

如果两个人对象,p1和p2为空,p1.equals(p2)应该返回什么?

  

结果为NullPointerException