我搜索了这些问题,但没有找到任何令人满意的答案。
在 Cpp/C++ 中,我可以使用对象地址来检查两个对象的地址,说这两个对象是相同的,或者是不同的对象但具有相同的值。在python中,我可以使用id方法来获取每个对象的ID 在java中,有没有不需要重新实现的方法hashCode()
来做到这一点?我想可能根据JVM,下次可能会释放和回收对象,那么java中没有这种方法吗?我对吗?
我搜索了这些问题,但没有找到任何令人满意的答案。
在 Cpp/C++ 中,我可以使用对象地址来检查两个对象的地址,说这两个对象是相同的,或者是不同的对象但具有相同的值。在python中,我可以使用id方法来获取每个对象的ID 在java中,有没有不需要重新实现的方法hashCode()
来做到这一点?我想可能根据JVM,下次可能会释放和回收对象,那么java中没有这种方法吗?我对吗?
我不打算在这里尝试答案,但需要更正。文档中的实际措辞是:
尽可能合理地实用,由 Object 类定义的 hashCode 方法确实为不同的对象返回不同的整数。(这通常通过将对象的内部地址转换为整数来实现,但 JavaTM 编程语言不需要这种实现技术。)
这不能保证哈希码是唯一的,只是实现尝试使它们唯一。此外,按理说,如果将一个 64 位物理地址(对于 64 位 JVM)折叠成一个 32 位哈希值,则必须存在别名,实际上每个哈希值有 40 亿个别名。
Java API 特别避免提供对物理地址的访问,因为它希望允许 JVM 使用复制收集器,其中对象的物理地址可以随时更改。
即使对于 32 位 JVM,如果有一个复制收集器,并且对象的哈希是在创建时从其地址计算的,那么该对象被复制到不同的代(通常发生),相同的哈希很可能是为在短暂(年轻)代的同一位置创建的不同新对象计算。
毫无疑问,由于性能开销,Java 默认不提供唯一 ID。如果需要,可以使用静态计数器自己实现它们,以便在各自的构造函数中分配唯一的 id,这很简单。
interface ObjectWithUniqueId {
public long getId();
}
class BaseObjectWithUniqueId implements ObjectWithUniqueId {
private static long currentId = 0;
private final long id;
// TODO Synchronize me if we are in a multithreaded environment!
public BaseObjectWithUniqueId() { id = ++currentId; }
public long getId() { return id }
}
答案是不。根据 Object.hashCode API the hashCode method defined by class Object does return distinct integers for distinct objects
。如果即使 Object.hashCode 是基于对象地址的,它也不能保证唯一性,因为 Java 对象可以通过 GC 在堆上移动。