왜 String은 자바에서 불변(Immutable)인가?

이 질문은 오래된 질문이지만 아직까지도 자바개발을 하는 개발자들이 자주 묻는 질문입니다. 여러가지 이유가 있지만 메모리, 동기화, 자료구조에 대한 이해도에 따라 대답이 달라지기도 합니다. 주요 이유를 알아보겠습니다.

 

1. String Pool에 대한 필요

String Pool은 자바의 힙영역에서 특수한 저장영역입니다. String 객체가 생성되고 만약 이미 기존에 같은 String 객체가 존재한다면 참조값은 새로운 객체가 아닌 기존의 String 객체로 정해지게 됩니다. 

다음의 코드는 heap영역에 하나의 String 객체만을 만들게 될 것입니다.

 

String string1 = “abcd”;
String string2 = “abcd”;

 

원리는 아래의 그림과 같습니다.

String 변수 두개의 참조 상태

문자열을 변경할 수 없는 경우, 하나의 참조로 문자열을 변경하면 다른 참조의 값이 잘못되게 됩니다. 

 

2. 문자열이 해시코드를 캐시하도록 함.(Allow String to Cache its Hashcode)

String의 hashcode는 자바(ex, HashMap)에서 아주 자주사용됩니다. 불변이라함은 해시코드가 언제나 같다는 것을 보증해줍니다. 그래서 변경사항을 걱정하지 않고 캐싱할 수 있습니다. 즉, 매번 해시코드를 비교할 필요가 없어지고 사용할 수 있게 됩니다. 비교과정만 없어져도 아주 효과적입니다.

 

3. 보안(Security)

- String은 자바의 파라미터로써 폭넓게 사용되는 객체입니다. 네트워크 커넥션, 파일 가져오기, JDBC에서의 드라이버명 등. String이 immutable하지 않았더라면 커넥션이나 파일은 그 정보가 변할 가능성이 생기며 아주 큰 보안문제로 이를 수 있습니다. 보안문제는 하나의 컴퓨터에만 연결하면 해결이 가능하다고 생각했지만 개발을 하시면 알겠지만 이것은 절대 그렇게 될 수 없는 문제입니다. 

또한. 리플렉션에서도 같은 문제가 발생할 수 있습니다. 다음의 코드를 보겠습니다.

 

boolean connect(string s){

	if (!isSecure(s)) { throw new SecurityException();}

	//etc code …

	//여기서 만약에 문자열 s가 매개변수로 전달되기전에 변경이 되었다면 문제를 일으킬 것입니다.

	causeProblem(s);
}

 

요약(In Summary)

디자인, 효율성, 보안등의 이슈때문이라고 생각하면 될 것 같습니다. 사실, 이는(디자인, 효율성, 보안) 대부분의 자바질문중에서 “왜 OOO입니까?”라는 질문에 대부분 답이 될만한 이슈들 입니다.

 

 

참조 : https://dzone.com/articles/why-string-immutable-java

댓글

Designed by JB FACTORY