디버깅 목적으로 Java에서 개체의 "개체 참조"를 인쇄하고 싶습니다. 즉, 상황에 따라 개체가 동일하거나 다른지 확인합니다.
문제는 해당 클래스가 일반적으로 ID를 제공하는 toString () 및 hashCode () 모두를 재정의 한 다른 클래스에서 상속된다는 것입니다.
상황 예 : 다중 스레드 응용 프로그램을 실행하는 경우 (개발 중) 모든 스레드가 리소스 개체의 동일한 인스턴스를 사용하는지 확인하려고합니다.
디버깅 목적으로 Java에서 개체의 "개체 참조"를 인쇄하고 싶습니다. 즉, 상황에 따라 개체가 동일하거나 다른지 확인합니다.
문제는 해당 클래스가 일반적으로 ID를 제공하는 toString () 및 hashCode () 모두를 재정의 한 다른 클래스에서 상속된다는 것입니다.
상황 예 : 다중 스레드 응용 프로그램을 실행하는 경우 (개발 중) 모든 스레드가 리소스 개체의 동일한 인스턴스를 사용하는지 확인하려고합니다.
답변:
정확히 무엇을 할 계획입니까 (당신이하고 싶은 일이 전화해야 할 일과 차이를 만듭니다).
hashCode
는 JavaDocs에 정의 된대로 다음과 같이 말합니다.
합리적으로 실용적인만큼 Object 클래스에 의해 정의 된 hashCode 메서드는 고유 한 개체에 대해 고유 한 정수를 반환합니다. (이것은 일반적으로 객체의 내부 주소를 정수로 변환하여 구현되지만 Java ™ 프로그래밍 언어에서는이 구현 기술이 필요하지 않습니다.)
따라서 hashCode()
메모리에서 고유 한 개체인지 확인하는 데 사용 하는 경우 좋은 방법이 아닙니다.
System.identityHashCode
다음을 수행합니다.
주어진 객체의 클래스가 hashCode ()를 재정의하는지 여부에 관계없이 기본 메소드 hashCode ()에 의해 반환되는 것과 동일한 해시 코드를 주어진 객체에 대해 반환합니다. 널 참조의 해시 코드는 0입니다.
당신이하고있는 일에 대해, 당신이 원하는 것처럼 들리지만 ... 당신이 원하는 것은 라이브러리가 어떻게 구현되었는지에 따라 안전하지 않을 수 있습니다.
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에서 코드를 복사하여 문자열의 참조를 얻을 수 있습니다.
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)));
}
}