Java clone() 查询

Java clone() inquiry

写完下面的代码后,我想知道为什么 clone() 不会 return 为每个额外的实例使用相同的哈希码。我做错了什么吗?

public class Accessor implements Cloneable {

    public static void main(String[] args) {

    Accessor one = new Accessor();
    Accessor two = one.clone();

    System.out.println("one hahcod  " + one.hashCode()
    +"\ntwo hashcode " + two.hashCode());    

    }

    public Accessor clone(){

        try{

            return (Accessor)super.clone();

        }
        catch (CloneNotSupportedException err){

            throw new Error("Error!!!");

        }
    }

}

因为是不同的对象。在这种情况下,您正在调用从 Object 继承的克隆。对于每个新对象,您将拥有不同的破折号。如果你打开java中Object的源代码,你会发现如下:

 public native int hashCode();

public boolean More ...equals(Object obj) {
        return (this == obj);
    }

这里的关键点是一旦你克隆了一个对象 A 克隆 ​​B A==B 总是 return false.

然后,如果您阅读 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. It is not required that if two objects are unequal according to the equals(java.lang.Object) method, then calling the hashCode method on each of the two objects must produce distinct integer results. However, the programmer should be aware that producing distinct integer results for unequal objects may improve the performance of hashtables.

由于 Accessor 不会覆盖 hashCode,您将获得 Object.hashCode 的默认实现。这具有实现定义的语义,但基本上会将对象的地址转换为整数,这样不同的对象实例将具有不同的 hashCodes.

有关上述内容的更多信息,请参阅 What is the default implementation of `hashCode`?

请注意,如果您要实施 hashCode,您还应该实施 equals。有关 equalshashCode 的良好参考,请阅读 Joshua Bloch 的 Effective Java(或参阅 Best implementation for hashCode method

clone 方法创建了第一个对象的浅表副本,但是您的 Accessor class 没有实例字段并且不会用您的对象覆盖 hashCode method, as a consequence the instances of this class get the default behaviour from Object class for hashCode. This behaviour is similar as calling System#identityHashCode作为参数。