当Java中的类不重写hashCode()时, 打印这个类的实例会得到一个很好的唯一编号。

Object的Javadoc说hashCode():

在合理实用的情况下,类Object定义的hashCode方法确实为不同的对象返回不同的整数。

但是当类重写hashCode()时,我如何获得 它唯一的数字?


当前回答

// looking for that last hex?
org.joda.DateTime@57110da6

如果你在对象上执行.toString()时查看hashcode Java类型,底层代码是这样的:

Integer.toHexString(hashCode())

其他回答

System.identityHashCode(yourObject)将给出yourObject的“原始”哈希码作为整数。独特性不一定得到保证。Sun JVM实现将为您提供一个与该对象的原始内存地址相关的值,但这是一个实现细节,您不应该依赖它。

编辑:回答修改以下汤姆的评论re.内存地址和移动对象。

如果它是一个可以修改的类,则可以声明一个类变量static java.util.concurrent.atomic.AtomicInteger nextInstanceId。(你必须以明显的方式给它一个初始值。)然后声明一个实例变量int instanceId = nextInstanceId.getAndIncrement()。

我想出了这个解决方案,在我的情况下,我有对象创建在多线程和序列化:

public abstract class ObjBase implements Serializable
    private static final long serialVersionUID = 1L;
    private static final AtomicLong atomicRefId = new AtomicLong();

    // transient field is not serialized
    private transient long refId;

    // default constructor will be called on base class even during deserialization
    public ObjBase() {
       refId = atomicRefId.incrementAndGet()
    }

    public long getRefId() {
        return refId;
    }
}

只是从另一个角度扩大其他答案。

如果你想重用来自“上面”的hashcode,并使用类的“不可变状态”派生新的hashcode,那么调用super就可以了。虽然这可能会/可能不会一直级联到Object(即某些祖先可能不会调用super),但它将允许您通过重用派生哈希码。

@Override
public int hashCode() {
    int ancestorHash = super.hashCode();
    // now derive new hash from ancestorHash plus immutable instance vars (id fields)
}
// looking for that last hex?
org.joda.DateTime@57110da6

如果你在对象上执行.toString()时查看hashcode Java类型,底层代码是这样的:

Integer.toHexString(hashCode())