Home String
Post
Cancel

String

String은 불변객체이다?

어떻게 String이 불변객체라는거지? “String이 불변객체라는 근거”와 “String을 불변객체로 설정한 이유”에 대해 알아보자.

String이 어떻게 불변객체이지?

String을 선언하는 방법은 2가지이다.

1
2
String str1 = "hello"; // 1번
String str2 = new String("hello"); // 2번

1번으로 저장하는 경우, “hello”는 String pool에 저장되고 2번으로 저장하게 되면, “hello”는 Heap에 저장된다.

String pool에 저장되면 같은 string이 들어왔을 경우, 같은 주소값을 뱉어내고 new 로 생성된 str은 같은 단어라도 매번 새로운 heap 주소값을 갖는다.

  • 증명
1
2
3
4
5
6
7
8
9
10
11
12
	public static void main(String[] args) {
		String str1 = "hello";
		String str2 = "hello";
		String str3 = new String("hello");
		String str4 = new String("hello");
		
		System.out.println("str1 = " + System.identityHashCode(str1)); // str1 = 1450495309
		System.out.println("str2 = " + System.identityHashCode(str2)); // str2 = 1450495309
		System.out.println("str3 = " + System.identityHashCode(str3)); // str3 = 1670782018
		System.out.println("str4 = " + System.identityHashCode(str4)); // str4 = 1706377736
	}

str1과 str2는 다르게 선언했지만 주소값이 동일하고 (String pool에 저장되었기떄문에 같은 문자면 같은 주소값을 반환한다.) str3과 str4는 동일한 문자이지만 매번 다른 주소값을 반환한다.

1번으로 선언이 되는 경우는 String pool에 저장되기때문에 불변의 성격을 갖는다.

img String pool은 heap 안에 존재한다. (java 8 ~)


String Interning

String을 String pool에 저장하고 사용하는 것을 String Interning으로 칭하고 String pool에 연관되어 intern()이라는 메소드가 존재한다.

1
2
3
4
5
6
String str1 = "hello";
String str2 = new String("hello");
String str3 = str2.intern();

System.out.println(str1 == str2); // false
System.out.println(str1 == str3); // true

String이 String pool에 존재하는 지 확인한다. 존재하는 경우 String pool의 주소값을 반환하고 없는 경우에는 String pool에 넣는다.

str2는 heap 에 저장됨 -> intern() -> str2인 “hello” 가 String pool 에 있는지 확인 -> String pool에 있기 때문에 str1의 주소값 반환한다.

그렇기때문에 str2은 heap에 저장되었지만 intern() 메소드로 str1의 주소값을 반환한다.

참고) == 연산자는 주소값을 비교한다.


그럼 왜 String을 불변객체로 설정했을까?

String 이 왜 불변객체 인지 알기 위해서는 String이 불변객체일 경우, 어떤 특징을 갖는지 알아야 한다.

여기서 불변객체 라는 것은 객체가 변수에 할당되고나서는 참조를 업데이트하거나 내부상태를 변경할 수 없음을 의미한다.

0. String이 불변객체이어야 String pool을 사용할 수 있다.

String이 불변이기에 String pool이 존재한다. 위에서 확인해봤다시피 같은 문자가 들어올 경우, String pool에서 같은 주소값을 반환하는데, 이 전제는 문자의 불변이다.

1. 안전하다.

불변객체는 상태를 변경할 수 없기때문에 여러 참조 변수들이 String 객체를 참조해도 안전하다.

2. 성능과 효율이 좋다.

java에서는 String을 많이 사용하는데, 사용할때마다 새로운 주소값을 할당받게 되면 메모리 낭비가 심해진다. 하지만 위에서 검증했다시피 String pool에 저장하게 되면 같은 문자일 경우, 같은 메모리 주소를 할당하기 때문에 불필요한 메모리 낭비가 없어서 성능에 좋기때문에 String을 불변객체로 설정했다.


String이 불변객체 라는 사실은 원인이 아니라, 결과이다.

This post is licensed under CC BY 4.0 by the author.

Java 질문과 정리

Annotation을 이용한 Validation