什么是Java合同

Pra*_*gla 5 java scjp

我正在为我的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;
    }
}
Run Code Online (Sandbox Code Playgroud)

题:

结果是什么?

  1. 输出为"true",MyStuff满足Object.equals()契约.
  2. 输出为"false",MyStuff履行Object.equals()契约.
  3. 输出为"true",MyStuff不符合Object.equals()契约.
  4. 输出为"false",MyStuff不符合Object.equals()契约.
  5. 编译失败.
  6. 运行时抛出异常.

答案是 -

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

我理解输出是true什么,以及为什么输出,但我没有得到的是,它怎么没有满足Object.equals()合同,以及Java中的"契约"究竟是什么,如果我们不遵守它会怎么样?

NIN*_*OOP 8

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

  1. 它是自反的:对于任何非空引用值x,x.equals(x)应该返回true.
  2. 对称性:对于任何非空的参考值x和y,x.equals(y)的应返回true,当且仅当y.equals(x)返回真.
  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;
}
Run Code Online (Sandbox Code Playgroud)

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


Sco*_*ion 3

这里的合同有英文含义,也有“Design by Contract”的约定。equals() 和 hashcode() 方法方面的契约可以在 Object 的 javadoc 上找到 - 我假设您已经阅读过它。

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