2017-11-29 28 views
0
class Employee { 
    String name; 

    Employee(String name) { 
    this.name = name; 
    } 
    // hashCode method is not overridden 
} 

public class HashCodeConfusion { 
    public static void main(String[] args) { 
    Employee emp = new Employee("ABC"); 
    Employee emp1 = new Employee("ABC"); 

    if (emp == emp1) { 
     System.out.println("Employee Same reference"); 
    } else { 
     System.out.println("Employee Different reference"); 
    } 
    if (emp.hashCode() == emp1.hashCode()) { 
     System.out.println("Employee Same hash code"); 
    } else { 
     System.out.println("Employee Different hash code"); 
    } 

    // ----------------------------------- 

    String str = new String("ABC"); 
    String str1 = new String("ABC"); 

    if (str == str1) { 
     System.out.println("String Same reference"); 
    } else { 
     System.out.println("String Different reference"); 
    } 
    if (str.hashCode() == str1.hashCode()) { 
     System.out.println("String Same hash code"); 
    } else { 
     System.out.println("String Different hash code"); 
    } 
    } 
} 

질문/혼란을 객체 : Object 클래스의 기본 해시 코드는 고려 객체 참조를 복용뿐 아니라 내용 것으로 보인다 , 왜 다른 것 직원 클래스 객체와 동일한 이름이 다른 해시 코드와 함께 나오게됩니까? Object 클래스의 기본 구현에 내용 만 기반한 해시 알고리즘이있는 경우 내 같음 패러다임이 비트 호환성과 일치하는 한 hashCode 메서드를 재정의해야 할 필요가 없습니다.다른 클래스에 비해 문자열의 해시 코드는

이 혼란을 없애기위한 것이 있습니까?

+0

기본 해시 코드는 _alone_ 참조에 생성됩니다. 여기서는 내용이 부적합합니다. 그러나 'String'이나 원시 래퍼와 같은 다른 클래스는 자체 콘텐트 기반 구현을 제공한다. 많은 경우에 클래스의 모든 필드가'equals()'와'hashCode()'에 의해 사용되는 것은 아니기 때문에 상자 밖에서 제공 될 수는 없습니다 (예를 들어'java.util.Date'를보십시오). 해시 코드를 제공하기 위해'cdate' 또는'fastTime'을 사용합니다 - 모든 필드를 사용하는 기본 구현은 그것을 결코 알 수 없습니다.) – Thomas

+0

"내용이 아니라 객체 참조를 고려한"및 내용이 아닌 *. –

답변

1

기본 hashCode()는이 아니며 시스템의 주소는 입니다. 헤더에 저장된 임의로 생성 된 번호입니다. 이렇게하면 hashCode()를 변경하지 않고 객체를 이동할 수 있고 hashCode는 비교적 임의적입니다.

참고 : 마이너 GC 후

  • 은 에덴 공간은 비어 있고 만든 첫 번째 객체는 항상 같은 주소에있다. hashCode가 같지 않습니다.
  • 개체는 기본적으로 8 바이트 경계에서 생성되므로 하위 3 비트는 모두 000 일 수 있으므로 hashCode에는 유용하지 않습니다. 압축 된 Oops를 사용하는 경우 하위 비트는 저장되지 않지만 여전히 임의적이지는 않습니다.
  • Unsafe을 사용하면 저장된 hashcode를 읽고 덮어 쓸 수 있습니다. OracleJVM/OpenJDK에서 hashCode는 오브젝트의 시작에서 1 바이트 씩 저장됩니다.
  • hashCode를 저장하는 데 사용되는 비트는 baised locking에도 사용됩니다. 객체에 대한 내장 hashCode를 얻으면 편향 잠금을 사용하지 않습니다.
  • System.identityHashCode(x) (IdentityMap 사용)을 사용하여 모든 객체의 시스템 hashCode를 얻을 수 있습니다.