在采用Object参数的Java方法中,如何访问仅存在于特定类实例的字段?

Joh*_*n P 1 java field object

- 是的,这是一个问题,需要帮助解决作为家庭作业的事情.不,这不是我要求你为我做功课.半个小时前的截止日期; 我确实无法改变我的提交.你只需要相信我的话.继续...

我知道测试对象类型应该是不必要的.当我在寻找有关'instanceof'的详细信息时,我找到了六个线程,人们只回应告诉原始的海报,如果他们必须进行测试以找出他们在处理之前处理的是什么类型的对象,他们就会犯错它.是的,我知道,我很乐意遵循这些惯例.不幸的是,我的教授要求我们覆盖我们定义的类的equals方法,特别是需要一个Object类型参数.如果你看到我的代码,你可能会更好地理解:

public boolean equals(Course other){
    if(!(other instanceof Course)){
        return false;
    } else if(other.name==this.name && other.days==this.days && 
        other.start==this.start && other.end==this.end){
        return true;
    }
    return false;
}
Run Code Online (Sandbox Code Playgroud)

你可以理解我要去哪里.'other'参数应该是Object类型,但如果我将它保留为Object并使用名称/ days/start/end字段,则该程序是合适的.如果我把它改成课程,当然它可以工作(没有双关语),但这将是一个完全不同的方法.所需的行为是除了Course实例之外的所有对象使该方法返回false,此外,对于Course实例之间的不匹配数据,使其返回false.

对于那些了解Java的人来说,通过看到这样的问题感到沮丧,我感到很遗憾.

jab*_*245 7

如果要覆盖"equals"方法,则应使用Object作为参数,因此必须检查对象的类型.通常你自己的实现看起来像这样:

@Override
public boolean equals(Object obj) {
    if (obj == this)
        return true;  // object's references are identical
    else if (!(obj instanceof Course))
        return false;

    Course that = (Course) obj;
    return (this.name.equals(that.name)) && (this.days == that.days)
        && (this.start.equals(that.start)) && (this.end.equals(that.end));
}
Run Code Online (Sandbox Code Playgroud)

当然你也应该使用相同的重要字段覆盖"hashCode".


相反,您使用自己的类型为Course的参数重载了该方法.所以,如果你myobject.equals(anotherObject)anotherObject没有类型的课程,你的"等于"方法永远不会被调用,而不是Object#equals方法将被调用,仅执行以下操作:return this == obj.


重载"equals"方法不够的原因是需要重载"hashCode",它不需要参数,因此不能重载.

  • 如果您编写自己的实现boolean equals(Object),则还必须实现int hashCode()
  • 两种方法都应该对"hashCode"和"equals"使用相同的重要字段.
  • 如果还必须符合a.equals(b) == true以下条件:a.hashCode() == b.hashCode()
  • 如果a.hashCode() != b.hashCode()那么a.equals(b) == false

最后一点是你不应该用你自己的类型重载"equals"的主要原因:

Course c1 = new Course("myname");
Course c2 = new Course("myname");
c1.equals(c2);                   // true
c1.hashCode() == c2.hashCode();  // false
Run Code Online (Sandbox Code Playgroud)