当我编译并运行下面的代码时,我得到以下结果:
o1==o2 ? true Hash codes: 0 | 0 o1==o2 ? true Hash codes: 1 | 8 o1==o2 ? true Hash codes: 7 | 3 o1==o2 ? true Hash codes: 68 | 10 o1==o2 ? true Hash codes: 5 | 4从我读过的内容来看,如果两个对象相等,它们的hashCode也必须相等。 那么,这段代码不会导致异常或错误?
import java.io.*; import java.lang.*; public class EqualsAndHashCode { private int num1; private int num2; public EqualsAndHashCode(int num1, int num2) { this.num1 = num1; this.num2 = num2; } public static void main(String[] args) { for (int x=0; x < 5; x++) { EqualsAndHashCode o1 = new EqualsAndHashCode(x, x); EqualsAndHashCode o2 = new EqualsAndHashCode(x, x); System.out.println("o1==o2 ? " + o1.equals(o2)); System.out.println("Hash codes: " + o1.hashCode() + " | " + o2.hashCode()); } } public boolean equals(Object o) { return (this.getNum1() == ((EqualsAndHashCode)o).getNum1()) && (this.getNum2() == ((EqualsAndHashCode)o).getNum2()); } public int hashCode() { return (int)(this.getNum1() / Math.random()); } public int getNum1() { return num1; } public int getNum2() { return num2; } }编辑我我的问题背后的前提是围绕hashCode合同( http://docs.oracle.com/javase/6/docs/api/java/lang/Object.html#hashCode() )的措辞:
如果两个对象根据equals(Object)方法相等,则对这两个对象中的每个对象调用hashCode方法必须产生相同的整数结果。
我认为这个规则会在编译或运行时由JVM执行,并且我会在违反合同时马上看到错误或异常。
When I compile and run the code below, I get the following results:
o1==o2 ? true Hash codes: 0 | 0 o1==o2 ? true Hash codes: 1 | 8 o1==o2 ? true Hash codes: 7 | 3 o1==o2 ? true Hash codes: 68 | 10 o1==o2 ? true Hash codes: 5 | 4From what I've read, if two objects are equal, their hashCodes must also be equal. So, how does this code not cause an exception or error?
import java.io.*; import java.lang.*; public class EqualsAndHashCode { private int num1; private int num2; public EqualsAndHashCode(int num1, int num2) { this.num1 = num1; this.num2 = num2; } public static void main(String[] args) { for (int x=0; x < 5; x++) { EqualsAndHashCode o1 = new EqualsAndHashCode(x, x); EqualsAndHashCode o2 = new EqualsAndHashCode(x, x); System.out.println("o1==o2 ? " + o1.equals(o2)); System.out.println("Hash codes: " + o1.hashCode() + " | " + o2.hashCode()); } } public boolean equals(Object o) { return (this.getNum1() == ((EqualsAndHashCode)o).getNum1()) && (this.getNum2() == ((EqualsAndHashCode)o).getNum2()); } public int hashCode() { return (int)(this.getNum1() / Math.random()); } public int getNum1() { return num1; } public int getNum2() { return num2; } }EDIT I The premise behind my question was the wording surrounding the hashCode contract (http://docs.oracle.com/javase/6/docs/api/java/lang/Object.html#hashCode()):
If two objects are equal according to the equals(Object) method, then calling the hashCode method on each of the two objects must produce the same integer result.
I assumed that this rule would have been enforced by the JVM at compile or run time and I would have seen errors or exceptions right away when the contract was violated...
最满意答案
因为JVM不检查或验证方法合约是否成立。 他们只是方法,他们可以返回他们想要的任何东西。
但是,依赖于他们的任何代码支持方法合约可能会或将会失败。 例如,您将无法在HashMap使用EqualsAndHashCode对象。 这会引发异常,或者在大多数情况下不会返回正确的值。
这与compareTo()和TreeMaps是一样的 - compareTo()可以返回它想要的任何int ,但是如果它没有返回Comparable接口中方法契约定义的一致的排序,那么你的TreeMap将会抛出异常只要它检测到不一致。
Because the JVM does not check or validate that the method contract holds true. They're just methods, and they can return whatever they want.
However, any code which depends upon them supporting the method contract might or will fail. You will not be able to use your EqualsAndHashCode objects in a HashMap, for example. That will throw exceptions or will not return correct values in most cases.
This is the same thing with compareTo() and TreeMaps - compareTo() can return any int that it wants, but if it doesn't return a consistent ordering as defined by the method contract in the Comparable interface, then your TreeMap will throw exceptions as soon as it detects inconsistencies.
更多推荐
发布评论