当 toString() 和 hashCode() 被覆盖时,如何在 Java 中获取对象的“对象引用”?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/580984/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do you get the "object reference" of an object in java when toString() and hashCode() have been overridden?
提问by Nicolai
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.
我想打印 Java 中对象的“对象引用”以进行调试。即根据情况确保对象相同(或不同)。
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.
问题是有问题的类继承自另一个类,该类已经覆盖了通常会给我 id 的 toString() 和 hashCode() 。
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.
示例情况:运行多线程应用程序,我(在开发期间)想检查是否所有线程都使用资源对象的相同实例。
采纳答案by TofuBeer
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:
hashCode
,如 JavaDocs 中所定义,说:
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.)
尽可能实用,类 Object 定义的 hashCode 方法确实为不同的对象返回不同的整数。(这通常通过将对象的内部地址转换为整数来实现,但 Java™ 编程语言不需要这种实现技术。)
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.
因此,如果您正在使用hashCode()
来确定它是否是内存中的唯一对象,那么这不是一个好方法。
System.identityHashCode
does the following:
System.identityHashCode
执行以下操作:
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.
为给定对象返回与默认方法 hashCode() 返回的相同的哈希码,无论给定对象的类是否覆盖 hashCode()。空引用的哈希码为零。
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.
对于您正在做的事情,这听起来像是您想要的……但是根据库的实现方式,您想要做的事情可能并不安全。
回答by Nicolai
This is how I solved it:
我是这样解决的:
Integer.toHexString(System.identityHashCode(object));
回答by Robin
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.
您不能安全地做您想做的事,因为默认的 hashCode() 可能不会返回地址,并且已经提到,多个对象可能具有相同的 hashCode。实现您想要的唯一方法是实际覆盖相关对象的 hashCode() 方法并保证它们都提供唯一值。这在您的情况下是否可行是另一个问题。
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.
作为记录,我在 WAS 服务器中运行的 IBM VM 中遇到了多个具有相同默认哈希码的对象。我们有一个缺陷,即放入远程缓存的对象会因此被覆盖。这让我大开眼界,因为我假设默认的哈希码也是对象内存地址。
回答by Robin
Add a unique id to all your instances, i.e.
为所有实例添加唯一 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; }
}
Extend from AbstractSomething and query this property. Will be safe inside a single vm (assuming no game playing with classloaders to get around statics).
从 AbstractSomething 扩展并查询此属性。在单个 vm 中将是安全的(假设没有使用类加载器玩游戏来解决静态问题)。
回答by noahlz
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).
==
无论对象的 hashCode 或 equals 的实现如何,双等于将始终根据对象标识进行检查。当然 - 确保您要比较的对象引用是volatile
(在 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:
如果您确实必须拥有原始 Object toString 结果(尽管它不是您的示例用例的最佳解决方案),Commons Lang 库有一个方法ObjectUtils.identityToString(Object)可以执行您想要的操作。来自 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.
如果类没有覆盖 toString 本身,则获取将由 Object 生成的 toString。null 将返回 null。
ObjectUtils.identityToString(null) = null
ObjectUtils.identityToString("") = "java.lang.String@1e23"
ObjectUtils.identityToString(Boolean.TRUE) = "java.lang.Boolean@7fa"
回答by Nikhil Jaitak
we can simply copy the code from tostring of object class to get the reference of string
我们可以简单地从对象类的 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)));
}
}