programing

toString()과 hashCode()가 오버라이드 되었을 때 자바에서 객체의 "객체 참조"를 얻으려면 어떻게 해야 합니까?

sourcetip 2022. 9. 19. 22:49
반응형

toString()과 hashCode()가 오버라이드 되었을 때 자바에서 객체의 "객체 참조"를 얻으려면 어떻게 해야 합니까?

디버깅을 위해 오브젝트의 "object reference"를 Java로 인쇄하고 싶습니다.즉, 상황에 따라 오브젝트가 같은(또는 다른)지 확인합니다.

문제는 해당 클래스가 다른 클래스에서 상속된다는 것입니다.이 클래스는 보통 ID를 제공하는 toString()과 hashCode()를 모두 덮어씁니다.

예:멀티 스레드 어플리케이션을 실행하고 있습니다.이 어플리케이션에서는 (개발 중에) 모든 스레드가 리소스 객체의 동일한 인스턴스를 사용하고 있는지 여부를 확인합니다.

이것으로 무엇을 할 예정입니까(무엇을 하고 싶은지에 따라 콜이 필요한지에 따라 다릅니다.

JavaDocs에 정의되어 있는 바와 같이 다음과 같습니다hashCode.

클래스 오브젝트에 의해 정의된hashCode 메서드는 합리적으로 실용적인 만큼 개별 오브젝트에 대해 개별 정수를 반환합니다.(일반적으로 개체의 내부 주소를 정수로 변환하여 구현하지만 Java™ 프로그래밍 언어에서는 이 구현 기술이 필요하지 않습니다.)

래래 so so so so를 사용하고 있는 hashCode()기억 속의 독특한 물체가 좋은 방법이 아닌지 알아내는 거죠.

System.identityHashCode 는 다음 작업을 수행합니다.

지정된 개체의 클래스가 hashCode()보다 우선하는지 여부에 관계없이 기본 메서드 hashCode()에서 반환되는 것과 동일한 해시 코드를 반환합니다.null 참조의 해시 코드는 0입니다.

네가 하고 있는 일치고는 네가 원하는 것처럼 들리는데...그러나 라이브러리가 구현되는 방법에 따라서는 안전하지 않을 수 있습니다.

이렇게 해결했습니다.

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

은 「」입니다.==는 항상 객체의 hashCode 또는 동등한 객체의 구현에 관계없이 객체 ID를 기반으로 체크합니다.물론 - 비교하는 오브젝트 참조가 다음 오브젝트 참조가volatile (1.5+JVM).

원래의 Object toString 결과가 꼭 필요한 경우(사용 예시는 최적의 솔루션이 아니지만), Commons Lang 라이브러리에는 원하는 것을 실행하는 ObjectUtils.identityToString(Object) 메서드가 있습니다.JavaDoc에서:

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

클래스가 toString 자체를 재정의하지 않은 경우 개체에서 생성되는 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 내에서 안전합니다(클래스로더를 사용하여 정적인 상태를 회피하는 게임이 없는 경우).

우리는 단순히 오브젝트 클래스의 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)));
  }
}

언급URL : https://stackoverflow.com/questions/580984/how-do-you-get-the-object-reference-of-an-object-in-java-when-tostring-and-h

반응형