문자열을 저장하기 위해서 char[] value를 인스턴스 변수로 정의하고 있는 클래스
한번 생성된 String은 변경할 수 없다!
-> +연산자를 이용해 문자열을 결합하는 경우 새로운 문자열이 담긴 인스턴스가 생성된다!
-> 따라서, 문자열을 다루는 작업이 필요한 경우는 StringBuffer클래스를 사용하자!
String literal = "abc";
String constr = new String("abc");
리터럴 지정: 같은 내용의 문자열을 모두 하나의 String인스턴스를 참조.
생성자: new를 통한 메모리 할당으로, 새로운 String 인스턴스 생성
String인스턴스의 문자열을 'constant pool'에 등록하는 메서드
이미 등록되어 있다면 문자열의 주소값을 반환함
intern()을 사용하면, equals 대신 ==를 사용할 수 있다.
-> 문자열의 개수가 많은 경우에는 equals보다 성능이 좋다!
String이 Object에서 상속받은 equals와 hashCode를 Object와 비교하며 보려고 한다.
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String aString = (String)anObject;
if (!COMPACT_STRINGS || this.coder == aString.coder) {
return StringLatin1.equals(value, aString.value);
}
}
return false;
}
// StringLatin1의 equals
@HotSpotIntrinsicCandidate
public static boolean equals(byte[] value, byte[] other) {
if (value.length == other.length) {
for (int i = 0; i < value.length; i++) {
if (value[i] != other[i]) {
return false;
}
}
return true;
}
return false;
}
Object를 상속받은 String 클래스는 equals()를 오버라이딩했다.
따라서, hashCode를 오버라이딩하지 않는다면, 새로운 객체를 만들 때 마다 Object클래스에 정의된 대로 모든 객체가 서로 다른 해시코드를 가질 것이다.
-> 그렇기때문에 equals를 오버라이딩할 때 hashCode메서드도 같이 오버라이딩해야한다?
//String
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;
}
//StringLatin1.java
public static int hashCode(byte[] value) {
int h = 0;
for (byte v : value) {
h = 31 * h + (v & 0xff);
}
return h;
}
가지고 있는 문자(value)를 hash해서 갖는다.
만약에 존재하지 않는다면 새로운 hash값이 생길테고, hash값이 존재한다면 그 존재하는 값을 가지게 된다.
하지만, String 코드에서 hash가 어떻게 사용하는지를 모르겠다.
내가 생각한 가정은,
이 고유한 해쉬가 constant pool에 존재하고, 같은 이름이 들어왔을 때 같은 해쉬값이 나오면, 그 해쉬 값을 기준으로 메모리를 찾아가 연결한다고 생각하였는데 이걸 증명할 수 있을만한 코드가 보이지 않는다.