5

我正在为我的 OCA 准备解决一些问题。我在 Oracle 的网站上发现了这个问题,列出了考试示例问题。

代码:

public class MyStuff {
    MyStuff(String n) { name = n; }
    String name;
    public static void main(String[] args) {
        MyStuff m1 = new MyStuff("guitar");
        MyStuff m2 = new MyStuff("tv");
        System.out.println(m2.equals(m1));
    }
    public boolean equals(Object o) {
        MyStuff m = (MyStuff)o;
        if(m.name != null) return true;
        return false;
    }
}

问题:

结果是什么?

  1. 输出为“真”并且 MyStuff 满足 Object.equals() 合同。
  2. 输出为“假”并且 MyStuff 满足 Object.equals() 合同。
  3. 输出为“真”并且 MyStuff 不履行 Object.equals() 合同。
  4. 输出为“假”并且 MyStuff 不履行 Object.equals() 合同。
  5. 编译失败。
  6. 运行时抛出异常。

答案是——

3. The output is "true" and MyStuff does NOT fulfill the Object.equals() contract.

我理解输出如何以及为什么是true,但我没有得到的是它为什么不履行Object.equals()合同,以及 Java 中的“合同”到底是什么,如果我们不遵守它怎么办?

4

4 回答 4

8

equals 方法在非空对象引用上实现等价关系:

  1. 它是自反的:对于任何非空引用值 x,x.equals(x) 应该返回 true。
  2. 它是对称的:对于任何非空引用值 x 和 y,当且仅当 y.equals(x) 返回 true 时,x.equals(y) 才应该返回 true。
  3. 它是可传递的:对于任何非空引用值 x、y 和 z,如果 x.equals(y) 返回 true 并且 y.equals(z) 返回 true,则 x.equals(z) 应该返回 true。
  4. 它是一致的:对于任何非空引用值 x 和 y,x.equals(y) 的多次调用始终返回 true 或始终返回 false,前提是没有修改对象上 equals 比较中使用的信息。对于任何非空引用值 x,x.equals(null) 应该返回 false。

以下方法不履行此义务对于任何非空引用值 x,x.equals(null) 应返回 false。

public boolean equals(Object o) {
    MyStuff m = (MyStuff)o;
    if(m.name != null) return true;
    return false;
}

这将抛出一个ClassCastException,如果onull,它应该理想地返回false

于 2013-06-11T07:49:25.570 回答
3

这里的合同有英文意思,也有“按合同设计”的约定。关于 equals() 和 hashcode() 方法的合同可以在 Object 的 javadocs 上找到——我假设你已经阅读过它。

为了更好地理解“按合同设计”范式,必须阅读维基百科页面。在 Java 中,通常定义接口以建立实现类必须遵守的约定。

于 2013-06-11T07:48:18.220 回答
3

阅读有关方法equals的文档Object

于 2013-06-11T07:48:31.933 回答
0

网友蝎子回答了什么是合约。

如果您没有完全履行合同,那么您的代码可能会出人意料地表现出来,例如当您使用 java Collections 时。我记得我的一位同事说:这个java Collection有一个bug,它不起作用。但这个错误是他的 equals 方法,不能与 hashcode() 一起工作

于 2013-06-11T08:28:22.607 回答