当toString()和hashCode()被覆盖的时候,如何获得java中对象的“对象引用”?
我想打印一个Java对象的“对象引用”用于debugging目的。 即根据情况确定对象是相同的(或不同的)。
问题是,有问题的类inheritance自另一个类,它重写了通常给我的id toString()和hashCode()。
示例情况:运行一个multithreading应用程序,其中我(在开发期间)要检查所有线程是否使用资源对象的相同实例。
你究竟打算做什么(你想做什么与你需要调用什么有所不同)。
在JavaDocs中定义的hashCode
说:
尽可能多地合理实用,由类Object定义的hashCode方法确实为不同的对象返回不同的整数。 (这通常通过将对象的内部地址转换为整数来实现,但Java™编程语言不需要此实现技术。)
所以,如果你正在使用hashCode()
来找出它是否是一个在内存中的唯一对象,这不是一个好办法。
System.identityHashCode
执行以下操作:
无论给定对象的类是否覆盖hashCode(),都将返回给定对象的哈希码,与默认方法hashCode()返回的哈希码相同。 空引用的散列码为零。
对于你在做什么来说,这听起来像你想要的,但是根据图书馆的实施情况,你想要做什么可能是不安全的。
这是我解决它的方法:
Integer.toHexString(System.identityHashCode(object));
Double equals ==
将始终根据对象标识进行检查,而不pipe对象是否实现了hashCode或equals。 当然 – 确保你比较的对象引用是volatile
(在1.5 + JVM中)。
如果你真的必须有最初的Object toString结果(虽然这不是你的示例用例的最佳解决scheme),Commons Lang库有一个方法ObjectUtils.identityToString(Object) ,它可以做你想做的事情。 从JavaDoc:
public static java.lang.String identityToString(java.lang.Object object)
获取如果一个类没有覆盖toString本身,将由Object产生的toString。 null将返回null。
ObjectUtils.identityToString(null) = null ObjectUtils.identityToString("") = "java.lang.String@1e23" ObjectUtils.identityToString(Boolean.TRUE) = "java.lang.Boolean@7fa"
由于默认的hashCode()可能不会返回地址,所以你不能安全地做你想做的事情,并且已经提到过,具有相同hashCode的多个对象是可能的。 实现你想要的唯一方法是实际重写所讨论对象的hashCode()方法,并保证它们都提供唯一的值。 在你的情况下这是否可行是另外一个问题。
为了logging,我在WAS服务器中运行的IBM VM中遇到了具有相同默认哈希码的多个对象。 我们有一个缺陷,放入远程caching的对象因此被覆盖。 这是我在这一点上大开眼界,因为我认为默认的哈希码也是对象的内存地址。
为您的所有实例添加一个唯一的ID,即
public interface Idable { int id(); } public class IdGenerator { private static int id = 0; public static synchronized int generate() { return id++; } } public abstract class AbstractSomething implements Idable { private int id; public AbstractSomething () { this.id = IdGenerator.generate(); } public int id() { return id; } }
从AbstractSomething扩展并查询此属性。 在单个虚拟机内部是安全的(假设没有游戏使用类加载器来解决静态问题)。
我们可以简单地从对象类的tostring中复制代码来获取string的引用
class Test { public static void main(String args[]) { String a="nikhil"; // it stores in String constant pool String s=new String("nikhil"); //with new stores in heap System.out.println(Integer.toHexString(System.identityHashCode(a))); System.out.println(Integer.toHexString(System.identityHashCode(s))); } }