如何获得“对象引用”? 当 toString() 和 hashCode() 被重写时,java中的对象的?

发布于 2024-07-13 22:13:23 字数 181 浏览 6 评论 0原文

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

问题是有问题的类继承自另一个类,该类重写了 toString() 和 hashCode() 这通常会给我 id。

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

I would like to print the "object reference" of an object in Java for debugging purposes.
I.e. to make sure that the object is the same (or different) depending on the situation.

The problem is that the class in question inherits from another class, which has overriden both toString() and hashCode() which would usually give me the id.

Example situation:
Running a multi-threaded application, where I (during development) want to check if all the threads use the same instance of a resource object or not.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

蹲墙角沉默 2024-07-20 22:13:23

您到底打算用它做什么(您想要做什么与您需要调用什么有所不同)。

hashCode< /a>,如 JavaDocs 中所定义,表示:

在相当实用的情况下,Object 类定义的 hashCode 方法确实为不同的对象返回不同的整数。 (这通常是通过将对象的内部地址转换为整数来实现的,但 Java™ 编程语言不需要这种实现技术。)

因此,如果您使用 hashCode() 来查找如果它是内存中的唯一对象,那么这不是一个好方法。

系统.identityHashCode 执行以下操作:

为给定对象返回与默认方法 hashCode() 返回的相同的哈希码,无论给定对象的类是否覆盖 hashCode()。 空引用的哈希码为零。

对于您正在做的事情,听起来像是您想要的......但是您想要做的事情可能不安全,具体取决于库的实现方式。

What exactly are you planning on doing with it (what you want to do makes a difference with what you will need to call).

hashCode, as defined in the JavaDocs, says:

As much as is reasonably practical, the hashCode method defined by class Object does return distinct integers for distinct objects. (This is typically implemented by converting the internal address of the object into an integer, but this implementation technique is not required by the Java™ programming language.)

So if you are using hashCode() to find out if it is a unique object in memory that isn't a good way to do it.

System.identityHashCode does the following:

Returns the same hash code for the given object as would be returned by the default method hashCode(), whether or not the given object's class overrides hashCode(). The hash code for the null reference is zero.

Which, for what you are doing, sounds like what you want... but what you want to do might not be safe depending on how the library is implemented.

静若繁花 2024-07-20 22:13:23

这就是我解决它的方法:

Integer.toHexString(System.identityHashCode(object));

This is how I solved it:

Integer.toHexString(System.identityHashCode(object));
浅浅淡淡 2024-07-20 22:13:23

Double equals == 将始终根据对象标识进行检查,无论对象的 hashCode 或 equals 实现如何。 当然 - 确保您正在比较的对象引用是易失性的(在 1.5+ JVM 中)。

如果您确实必须拥有原始的 Object toString 结果(尽管这不是您的示例用例的最佳解决方案),Commons Lang 库有一个方法 ObjectUtils.identityToString(Object) 它将执行您想要的操作。 来自 JavaDoc:

public static java.lang.String identityToString(java.lang.Object object)

获取 toString
如果类没有,则由 Object 生成
覆盖 toString 本身。 空意志
返回空值。

 ObjectUtils.identityToString(null)         = null
 ObjectUtils.identityToString("")           = "java.lang.String@1e23"
 ObjectUtils.identityToString(Boolean.TRUE) = "java.lang.Boolean@7fa"

Double equals == will always check based on object identity, regardless of the objects' implementation of hashCode or equals. Of course - make sure the object references you are comparing are volatile (in a 1.5+ JVM).

If you really must have the original Object toString result (although it's not the best solution for your example use-case), the Commons Lang library has a method ObjectUtils.identityToString(Object) that will do what you want. From the JavaDoc:

public static java.lang.String identityToString(java.lang.Object object)

Gets the toString that would be
produced by Object if a class did not
override toString itself. null will
return null.

 ObjectUtils.identityToString(null)         = null
 ObjectUtils.identityToString("")           = "java.lang.String@1e23"
 ObjectUtils.identityToString(Boolean.TRUE) = "java.lang.Boolean@7fa"
む无字情书 2024-07-20 22:13:23

你不能安全地做你想做的事,因为默认的 hashCode() 可能不会返回地址,并且已经提到过,多个对象可能具有相同的 hashCode。 实现您想要的唯一方法是实际重写相关对象的 hashCode() 方法并保证它们都提供唯一的值。 这对于您的情况是否可行是另一个问题。

根据记录,我在 WAS 服务器中运行的 IBM VM 中遇到了具有相同默认哈希码的多个对象。 我们有一个缺陷,放入远程缓存的对象会因此被覆盖。 这让我大开眼界,因为我假设默认的哈希码也是对象的内存地址。

You cannot safely do what you want since the default hashCode() may not return the address, and has been mentioned, multiple objects with the same hashCode are possible. The only way to accomplish what you want, is to actually override the hashCode() method for the objects in question and guarantee that they all provide unique values. Whether this is feasible in your situation is another question.

For the record, I have experienced multiple objects with the same default hashcode in an IBM VM running in a WAS server. We had a defect where objects being put into a remote cache would get overwritten because of this. That was an eye opener for me at that point since I assumed the default hashcode was the objects memory address as well.

帅冕 2024-07-20 22:13:23

向所有实例添加唯一的 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 扩展并查询此属性。 在单个虚拟机内是安全的(假设没有使用类加载器玩游戏来绕过静态)。

Add a unique id to all your instances, i.e.

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; }
}

Extend from AbstractSomething and query this property. Will be safe inside a single vm (assuming no game playing with classloaders to get around statics).

愚人国度 2024-07-20 22:13:23

我们可以简单地从对象类的 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)));
  }
}

we can simply copy the code from tostring of object class to get the
reference of 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)));
  }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文