public class MyClass {
public static void main(String args[]) {
String text = "a";
String text2 = "a";
String text3 = new String("a");
System.out.println(text == text2); // true
System.out.println(text == text3); // false
System.out.println(text.equals(text3)); // true
}
}
자바에는 String Constant Pool이라는 것이 존재하기 때문에 동일한 값을 갖는 객체가 있으면 이미 만든 객체를 재사용 합니다.
따라서 text 객체와 text2 객체는 같은 객체입니다.
만약 Constant Pool을 이용하지 않고, heap에 새로운 객체를 생성하고 싶다면,
String text3 = new String("a"); 처럼 new 예약어를 사용해서 생성 하면 됩니다.
위 예제를 참고하면 text와 text2는 같은 인스턴스 객체이고, text와 text3는 다르다는 것을 알 수 있습니다.
객체가 다르다는 것은 서로 다른 주소값을 가진다는 의미 입니다.
System.out.println(text.hashCode()==text3.hashCode()); // true
System.out.println(text.hashCode()); // 97
System.out.println(text3.hashCode()); // 97
hashCode의 출력값이 같음을 확인 할 수 있습니다.
자바 공식 문서를 참고해보면 아래와 같은 설명을 확인할 수 있습니다.
public int hashCode()
Returns a hash code for this string. The hash code for a String object is computed as
s[0]31^(n-1) + s[1]31^(n-2) + ... + s[n-1]
using int arithmetic, where s[i] is the ith character of the string, n is the length of the string, and ^ indicates exponentiation. (The hash value of the empty string is zero.)
이 문장을 해석해보면,
이 문자열의 해시 코드를 반환합니다. String 객체의 해시 코드는 다음과 같이 계산됩니다.
s[0] x 31^(n-1) + s[1] x 31^(n-2) + ... + s[n-1]
int 산술을 사용합니다. 여기서 s[i]는 문자열의 i번째 문자이고, n은 문자열의 길이이며, ^는 지수를 나타냅니다. (빈 문자열의 해시 값은 0입니다.)
이 설명을 통해 String 객체의 해시 코드가 오버라이딩 되어 사용된 것을 확인 할 수 있습니다.
a = 97b = 98c = 99이제 위 String hashCode()의 수식에 대입하면 :
97 x 31^(3-1) + 98 x 31^(3-2) + 99 x 31^(3-3)
계산하면 :
97 x 961 + 98 x 31 + 99 x 1
= 93217 + 3038 + 99
= 96354
즉, "abc".hashCode()는 96354 입니다.
Java의 String.hashCode()는 각 문자에 31의 거듭제곱을 곱해서 더하는 방식으로 계산되기 때문에 text와 text3은 다른 객체지만 같은 해시 코드가 출력된다는 것을 알았습니다.
System 클래스의 identityHashCode를 출력하면 됩니다.
System.out.println(System.identityHashCode(text)); // 1157783951
System.out.println(System.identityHashCode(text2)); // 1157783951
System.out.println(System.identityHashCode(text3)); // 1933863327
identityHashCode 는 재정의된 hashCode()와 상관없이 객체가 가지고 있는 해시 코드를 출력해주는 메소드 입니다.
위 코드를 참고하면, text와 text3이 다른 해시 코드를 가지고 있다는 것을 확인 할 수 있습니다.