Java中的合同是什么
我正在为我的OCA准备解决一些问题。我在Oracle的网站上发现了这个问题,该网站列出了考试的样本问题 代码: 问题: 结果如何Java中的合同是什么,java,scjp,Java,Scjp,我正在为我的OCA准备解决一些问题。我在Oracle的网站上发现了这个问题,该网站列出了考试的样本问题 代码: 问题: 结果如何 输出为“true”,MyStuff实现Object.equals()契约 输出为“false”,MyStuff实现Object.equals()契约 输出为“true”,MyStuff不满足Object.equals()契约 输出为“false”,MyStuff不满足Object.equals()契约 编译失败 在运行时引发异常 答案是- 3。输出为“true”,My
3。输出为“true”,MyStuff不满足Object.equals()契约代码>
我理解输出是如何以及为什么是真的,但我不明白的是,它为什么没有完全满足对象.equals()
契约,Java中的“契约”到底是什么,如果我们不遵守它会怎么样?这里的契约具有英语含义以及“契约设计”的约定。equals()和hashcode()方法的契约可以在Object的javadocs上找到——我假设您已经阅读了它
维基百科是更好地理解“契约式设计”范式的必读书籍。在Java中,接口通常被定义为建立一个契约,然后实现类必须遵守该契约。阅读equals
对象的方法的文档
equals方法在非null对象引用上实现等价关系:
它是自反的:对于任何非空参考值x,x.equals(x)应该返回true
它是对称的:对于任何非空的引用值x和y,当且仅当y.equals(x)返回true时,x.equals(y)才应返回true
它是可传递的:对于任何非空引用值x、y和z,如果x.equals(y)返回true,y.equals(z)返回true,那么x.equals(z)应该返回true
它是一致的:对于任何非空的引用值x和y,x.equals(y)的多次调用始终返回true或false,前提是没有修改对象上equals比较中使用的信息。
对于任何非空引用值x,x.equals(null)应返回false
以下方法不履行此义务对于任何非空参考值x,x.equals(null)应返回false。
这将抛出一个ClassCastException
,如果o
为null
,理想情况下,它应该返回false
用户蝎子回答了什么是合同
如果您没有完全履行合同,那么您的代码可能会表现出未预期的行为,例如当您使用java集合时。我记得我的一位同事说过:这个java集合有一个bug,它不工作。但是错误是他的equals方法,没有与hashcode()一起工作。但是这段代码还是不好的,因为equals()
方法不应该抛出ClassCastException
,如果向该方法提供了另一个对象。如果o
为null,它将在取消对名称的引用时抛出NPE。如果o
为非空且不是MyStuff
类型,它将抛出一个CCE。这两种方法都不符合约定。如果我们不按约定进行设计怎么办?@PrateekSingla您读过wiki页面吗?在您的示例中,如果您不遵守对象类中equals()和hashcode()方法公开的约定,您将遇到代码错误,因为您的代码将表现出非确定性(考虑将此对象放入一个集合中,您可能无法使用不同的“equal”引用检索它)。是否使用“合同设计”无关紧要是否:如果您不遵守您编写或使用的代码中的约定,那么您可能会有严重的bug/错误代码。Javadoc说-请注意,每当重写hashCode方法时,通常有必要重写该方法,以便维护hashCode方法的一般约定,该约定声明相等的objects必须具有相等的哈希代码
,它表示要覆盖哈希代码以维护其契约,但没有说明equals方法。
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;
}
}
public boolean equals(Object o) {
MyStuff m = (MyStuff)o;
if(m.name != null) return true;
return false;
}