我想在Java中打印对象的“对象引用”以进行调试。 即根据具体情况确保对象相同(或不同)。
问题是有问题的类继承自另一个类,它已经覆盖了toString()和hashCode(),这通常会给我id。
示例情况: 运行多线程应用程序,我(在开发期间)想要检查所有线程是否使用相同的资源对象实例。
答案 0 :(得分:97)
你究竟打算用它做什么(你想做什么会影响你需要调用的东西)。
如JavaDocs中所定义的 hashCode
说:
尽可能合理,Object类定义的hashCode方法确实为不同的对象返回不同的整数。 (这通常通过将对象的内部地址转换为整数来实现,但Java™编程语言不需要此实现技术。)
因此,如果您使用hashCode()
来查明它是否是内存中的唯一对象,那么这不是一个好方法。
System.identityHashCode
执行以下操作:
返回与默认方法hashCode()返回的给定对象相同的哈希码,无论给定对象的类是否覆盖hashCode()。空引用的哈希码为零。
对于你正在做的事情,听起来像你想要的......但是你想要做的事情可能不安全,这取决于图书馆的实施方式。
答案 1 :(得分:47)
这就是我解决它的方法:
Integer.toHexString(System.identityHashCode(object));
答案 2 :(得分:8)
Double equals ==
将始终基于对象标识进行检查,无论对象的hashCode或equals的实现如何。当然 - 确保您要比较的对象引用是volatile
(在1.5+ JVM中)。
如果你真的必须拥有原始的Object toString结果(虽然它不是你的示例用例的最佳解决方案),Commons Lang库有一个方法ObjectUtils.identityToString(Object)可以做你想要的。来自JavaDoc:
public static java.lang.String identityToString(java.lang.Object object)
获取可能的toString 如果一个类没有,则由Object生成 覆盖toString本身。 null会 return null。
ObjectUtils.identityToString(null) = null
ObjectUtils.identityToString("") = "java.lang.String@1e23"
ObjectUtils.identityToString(Boolean.TRUE) = "java.lang.Boolean@7fa"
答案 3 :(得分:4)
您无法安全地执行您想要的操作,因为默认的hashCode()可能不会返回该地址,并且已经提到过,具有相同hashCode的多个对象是可能的。实现所需内容的唯一方法是实际覆盖有问题对象的hashCode()方法,并保证它们都提供唯一值。在你的情况下这是否可行是另一个问题。
为了记录,我在WAS服务器中运行的IBM VM中遇到了具有相同默认哈希码的多个对象。我们遇到了一个缺陷,即由于这个原因,被放入远程缓存的对象会被覆盖。这对我来说是个大开眼界,因为我假设默认的哈希码也是对象的内存地址。
答案 4 :(得分:2)
为所有实例添加唯一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扩展并查询此属性。在单个虚拟机内部是安全的(假设没有游戏与类加载器一起玩以解决静态问题)。
答案 5 :(得分:0)
我们可以简单地从对象类的tostring复制代码来获取 字符串
的引用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)));
}
}