Java 当对象o为null时,无法在equals()方法中返回false。我已经添加了equals()实现以及测试用例

Java 当对象o为null时,无法在equals()方法中返回false。我已经添加了equals()实现以及测试用例,java,oop,junit,compilation,Java,Oop,Junit,Compilation,我的equals()方法: 例如,在第二个if语句中,当我的对象为null时,我应该返回false,但由于某种原因,我的代码未能返回false。有什么帮助吗 public boolean equals(Prof o) { boolean res = false; if(this == o) { res = true; } if(o == null || this.getClass() != o.getClass()) {

我的equals()方法: 例如,在第二个if语句中,当我的对象为null时,我应该返回false,但由于某种原因,我的代码未能返回false。有什么帮助吗

public boolean equals(Prof o) {

    boolean res = false;
    
    if(this == o) {
        res = true;
    }
    if(o == null || this.getClass() != o.getClass()) {
        res = false; 
    }
    Prof other = (Prof) o;
    if(this.year == other.year) { 
        if(this.id.equals(other.id)) {
            res = true; 
            }
    }
    else {
        res = false;
    }
    return res;   
}
测试用例:

public void test02_ProfEqualHash() {

    Prof  p1 = new Prof("John S Lee", "yu213", 5);
     
    assertTrue(p1.equals(p1));
    
    Prof p0 = null; // null
    assertFalse(p1.equals(p0));  // my equals() implementation fails here 
    
    Date d = new Date();
    String s = "Hello";
    assertFalse(p1.equals(d)); 
    assertFalse(p1.equals(s));  
    
    
    Prof  p2 = new Prof("John L", "yu213", 5);  
    assertTrue(p1.equals(p2));
     
    assertTrue(p1.hashCode() == p2.hashCode());
     
    assertTrue(p2.equals(p1)); 
    
    Prof  p3 = new Prof("John S Lee", "yu203", 5); 
    assertFalse(p1.equals(p3));
     
    //assertNotEquals(p1.hashCode(), p3.hashCode());  
    
    Prof  p4 = new Prof("Tracy T", "yu053", 2);
    assertFalse(p1.equals(p4));
    //assertNotEquals(p1.hashCode(), p4.hashCode()); 
    
    Prof  p5 = new Prof("John S Lee", "yu213", 8); 
    assertFalse(p1.equals(p5));
    //assertTrue(p1.hashCode() != p5.hashCode());
    
}

首先,为了正确覆盖
对象的
equals()
,方法签名应该是:

public boolean equals(Object o) {
    ....
}
即使测试代码调用了
equals()
方法,但期望
对象
equals()
签名的JDK类也不会调用

此外,当您发现
o
参数为
null
时,应立即返回
false
,以免以后在方法中访问它(这将导致
NullPointerException

正确的实现可以如下所示:

public boolean equals (Object o) 
{
    if (this == o) {
        return true;
    }
    if (o == null || !(o instanceof Prof)) {
        return false; 
    }
    Prof other = (Prof) o;
    return this.year == other.year && this.id.equals(other.id);
}

在Java中,对象类是每个类的超类。因此,为了覆盖对象类中定义的equal方法,您需要遵循相同的方法定义,即:

@覆盖
公共布尔等于(对象其他){
//这是您的实现类
}
由于您对
equals
的定义将
Prof
作为参数,因此您实际上并没有重写对象
equals
方法

有关
equals
合同的更多信息,请阅读
Josh Bloch
Effective Java
一书

另外,如果您的类有一个equals方法,那么您也应该始终定义hashCode实现。以下是此方法的实现:

@覆盖
公共int hashCode(){
返回Objects.hash(年份,id);
}

在更正代码后,我现在可以返回false,但我的代码在assertTrue处停止(p1.hashCode()==p2.hashCode());我仍在学习强制方法,不知道如何通过这个hashCode()测试用例。任何输入都将是appreciated@Nzed您应该重写
int hashCode()
方法。如果两个对象相等,则它们应该具有相同的哈希代码。换句话说,
hashCode()
应该返回一个
int
,这是您在
equals()
中比较的所有属性的函数。我认为您在测试用例中得到了一个NPE,因为在您的实现中,other.year将导致NPE,因为另一个是nul。我通过了该语句。我能够返回false。非常感谢。我的代码在assertTrue处停止(p1.hashCode()==p2.hashCode());我仍在学习强制方法,不知道如何通过这个hashCode()测试用例。如果您阅读了我在回答中提到的条目10,那么任何输入都是值得的。它说,如果您希望对象具有可比性,那么您应该始终在类中实现hashcode方法。我猜您还没有在类中实现hasCode方法。另外,如果您使用的是Intellij之类的IDE,那么IDE将为您生成此方法。我需要一些帮助来实现它,因为我对强制性方法非常陌生。我现在会研究第11项,谢谢。我的建议是:在if条件下,立即返回您已经确定的正确或错误
if(o==null)返回false在其他条件下相同。此外,参数必须是对象o