2025. 1. 26. 22:14ㆍ개발/Java
String은 값을 할당하는 방법이 2가지가 있다.
String str1 = new String("hello");
String str2 = "hello";
new String으로 할당하면 이는 Heap 메모리에 올라가게 되고
Literal로 할당을 하면 String pool에 저장이 된다.
Literal로 값을 할당하면 나중에 같은 내용의 String이 있을 때 새로운 객체를 생성하지 않고 기존 객체를 참조한다.
그럼 아래와 같은 결과를 얻을 수 있다.
@Test
void test() {
String s = "hello";
String s2 = "hello";
assertThat(s == s2).isTrue();
}
반면에 new로 할당을 하면 Heap 메모리에 올라가게 되므로 String pool에 같은 문자열이 있다 하더라도 Heap에 새로운 객체를 만들게 된다.
@Test
void stringTest() {
String s1 = "hello";
String s2 = new String("hello");
assertThat(s1 == s2).isFalse();
assertThat(s1.equals(s2)).isTrue();
}
그럼 String의 equals()를 살펴보자(Java21 기준)
/**
* Compares this string to the specified object. The result is {@code
* true} if and only if the argument is not {@code null} and is a {@code
* String} object that represents the same sequence of characters as this
* object.
**/
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
return (anObject instanceof String aString)
&& (!COMPACT_STRINGS || this.coder == aString.coder)
&& StringLatin1.equals(value, aString.value);
}
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;
}
설명에도 써있지만 the same sequence of characters 일 때 true를 반환한다는 것을 알 수 있다.
그럼 `COMPACT_STRINGS`과 `coder` 는 무엇인가?
COMPACT_STRINGS가 나오게 된 배경은 다음과 같다.
Java 9 이전에는 String을 UTF-16(2byte)기반의 char[]로 저장했는데
// Java 8의 String class
public final class String
implements java.io.Serializable, Comparable<String>, CharSequence {
/** The value is used for character storage. */
private final char value[];
}
대부분의 String은 ASCII라는 점에서 메모리의 낭비가 심했다. 그래서 Java9에서 Compact Strings라는 것이 도입이 되었고 ASCII 문자열은 1바이트 배열로 저장, Non-ASCII 문자열은 UTF-16 배열로 저장한다. COMPACT_STRINGS 은 Compact Strings 기능의 활성화 여부를 나타내는 정적 상수이다.
coder는 String 객체가 어떤 인코딩 형식으로 저장되었는지를 나타내는 필드이다.
ASCII 문자열이면 coder값은 0, Non-ASCII 문자열이면 coder값은 1 이다.
ASCII 문자열 예시 - "hello"
Non-ASCII 문자열 예시 - "안녕하세요"
만약 섞여 있다면? ex) "hello안녕하세요" → Non-ASCII(UTF-16, 2byte)
'개발 > Java' 카테고리의 다른 글
| Reflection과 객체 생성 (0) | 2024.12.02 |
|---|---|
| equals()와 hashcode() (0) | 2024.11.30 |
| ThreadLocal과 ThreadLocalMap (0) | 2024.11.17 |
| Mutex와 Semaphore (0) | 2024.10.20 |
| 메모리 가시성 (0) | 2024.10.20 |