当toString()和hashCode()被覆盖时,如何获取java中对象的“对象引用”?

时间:2009-02-24 08:52:49

标签: java object hashcode

我想在Java中打印对象的“对象引用”以进行调试。 即根据具体情况确保对象相同(或不同)。

问题是有问题的类继承自另一个类,它已经覆盖了toString()和hashCode(),这通常会给我id。

示例情况: 运行多线程应用程序,我(在开发期间)想要检查所有线程是否使用相同的资源对象实例。

6 个答案:

答案 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)));
  }
}