デバッグの目的で、Javaでオブジェクトの「オブジェクト参照」を出力したいと思います。つまり、状況に応じてオブジェクトが同じ(または異なる)ことを確認します。
問題は、問題のクラスが別のクラスを継承していることです。これにより、通常はIDを取得するtoString()とhashCode()の両方がオーバーライドされます。
状況例:すべてのスレッドがリソースオブジェクトの同じインスタンスを使用しているかどうかを(開発中に)確認したい、マルチスレッドアプリケーションの実行。
デバッグの目的で、Javaでオブジェクトの「オブジェクト参照」を出力したいと思います。つまり、状況に応じてオブジェクトが同じ(または異なる)ことを確認します。
問題は、問題のクラスが別のクラスを継承していることです。これにより、通常はIDを取得するtoString()とhashCode()の両方がオーバーライドされます。
状況例:すべてのスレッドがリソースオブジェクトの同じインスタンスを使用しているかどうかを(開発中に)確認したい、マルチスレッドアプリケーションの実行。
回答:
正確に何を計画していますか(何をしたいかによって、何を呼び出す必要があるかが異なります)。
hashCode
は、JavaDocsで定義されているように述べています。
合理的に実用的である限り、Objectクラスによって定義されたhashCodeメソッドは、個別のオブジェクトに対して個別の整数を返します。(これは通常、オブジェクトの内部アドレスを整数に変換することによって実装されますが、この実装手法はJava™プログラミング言語では必要ありません。)
したがってhashCode()
、メモリ内の一意のオブジェクトであるかどうかを確認するために使用している場合、それを行うのは良い方法ではありません。
System.identityHashCode
次のことを行います。
指定されたオブジェクトのクラスがhashCode()をオーバーライドするかどうかに関係なく、デフォルトのメソッドhashCode()によって返されるのと同じ、指定されたオブジェクトのハッシュコードを返します。null参照のハッシュコードはゼロです。
これは、あなたがしていることに対して、あなたが望むもののように聞こえます...しかし、あなたがしたいことは、ライブラリの実装方法によっては安全ではないかもしれません。
double equals ==
は、オブジェクトのhashCodeまたはequalsの実装に関係なく、常にオブジェクトIDに基づいてチェックします。もちろん-比較するオブジェクト参照が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はnullを返します。
ObjectUtils.identityToString(null) = null
ObjectUtils.identityToString("") = "java.lang.String@1e23"
ObjectUtils.identityToString(Boolean.TRUE) = "java.lang.Boolean@7fa"
デフォルトのhashCode()はアドレスを返さない可能性があり、言及されているように、同じhashCodeを持つ複数のオブジェクトが存在する可能性があるため、安全に望むことを行うことができません。目的を達成する唯一の方法は、問題のオブジェクトのhashCode()メソッドを実際にオーバーライドし、それらすべてが一意の値を提供することを保証することです。これがあなたの状況で実現可能かどうかは別の問題です。
記録のために、私はWASサーバーで実行されているIBM VMで同じデフォルトのハッシュコードを持つ複数のオブジェクトを経験しました。このため、リモートキャッシュに置かれているオブジェクトが上書きされるという欠陥がありました。私はデフォルトのハッシュコードもオブジェクトのメモリアドレスであると想定していたので、それはその時点で私にとって目を開かせました。
すべてのインスタンスに一意の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から拡張し、このプロパティをクエリします。単一のvm内で安全になります(静的を回避するためにクラスローダーを使用してゲームをプレイしない場合)。
sun.misc.Unsafe
オブジェクトクラスの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)));
}
}