String - hashCode()
public final class String
i mplements java.io.Serializable, Comparable<String>, CharSequence,
Constable, ConstantDesc {
private boolean hashIsZero;
private int hash;
static final boolean COMPACT_STRINGS;
private final byte coder;
@Native static final byte LATIN1 = 0;
@Stable private final byte[] value;
public int hashCode() {
int h = hash;
if (h == 0 && !hashIsZero) {
h = isLatin1() ? StringLatin1.hashCode(value)
: StringUTF16.hashCode(value);
if (h == 0) {
hashIsZero = true;
} else {
hash = h;
}
}
return h;
}
boolean isLatin1() {
return COMPACT_STRINGS && coder == LATIN1;
}
=======================================================
final class StringLatin1 {
public static int hashCode (byte[] value) {
return switch (value.length) {
case 0 -> 0;
case 1 -> value[0] & 0xff;
default -> ArraysSupport.vectorizedHashCode(value, 0, value.length, 0, ArraysSupport.T_BOOLEAN);
};
}
}
=======================================================
final class StringUTF16 {
public static int hashCode(byte[] value) {
return switch (value.length) {
case 0 -> 0;
case 2 -> getChar(value, 0);
default -> ArraysSupport.vectorizedHashCode(value, 0, value.length >> 1, 0, ArraysSupport.T_CHAR);
};
}
}
착각
hashIsZero 가 왜 존재하는 건지, 한 번 hashCode 를 계산하고 나면 사라지는 블록변수 아닌가? 라고 생각했음
원인
String 을 단순히 문자열로만 사용을 해서 부지불식간에 아래의 내용을 잊고 있었던 것
String 클래스의 인스턴스의 참조값을 가지는 str 은 String 의 인스턴스이기 때문에 문자열인 value 말고도 hash 와 hashIsZero, coder 등을 필드값으로 가지고 있다
그 필드값들이 String 이 가진 메서드를 통해서 계산이 되는 것
따라서 hashIsZero 가 true 인지 false 인지에 따라서 재계산이 되고 말고가 결정되는 것