Java String의 속성에 관하여
아래 자바 코드는 몇 개의 오브젝트를 생성할까요?
String str1 = new String("gabbar");
String str2 = new String("gabbar");
String str3 = "gabbar";
그리고 아래 코드가 실행된 결괏값은 어떨까요?
System.out.println( str1 == str1.intern() );
System.out.println( str3 == str1.intern() );
자바에서 String은 특별한 참조 자료형입니다.
String 객체는 new 생성자를 이용해서 생성할 수 도있고, str3와 같이 두개의 큰따옴표 안에 값을 입력해서 생성할 수도 있습니다.
두 생성 방식 모두 String 객체를 생성해서 이용한다는 사실은 같지만, 다른 점이 있습니다.
바로 생성되는 메모리 영역입니다.
아래 그림은 두 가지 다른 방법으로 String 객체를 생성하였을 때, 자바 메모리에서는 어떻게 이 객체를 관리하는지 설명하고 있습니다. (출처 : http://www.journaldev.com/797/what-is-java-string-pool )
다시 말씀드리지만 자바의 String은 특별한 '참조 자료형'입니다. new 생성자를 이용해서 인스턴스를 만들고, heap 메모리에서 관리한다는 사실은 다른 참조 자료형과 다를게 없지만, 다른 참조 자료형과는 다른 immutable 하다는 특징을 가지고 있습니다. 즉, 한번 객체가 생성돼서 저장된 값은 변하지 않습니다.
그러면 위 그림에서 s3 = s3 + s3; 를 실행하면 어떻게 될까요?
CatCat 값을 가지는 String 객체를 새로 생성하고, s3는 그 인스턴스를 참조하게 됩니다.
이렇듯 String 연산은 새로운 객체를 계속 만들어 내기 때문에, 메모리 관리 측면에서 비효율적입니다.
그래서 만들어진 메모리 영역이 String Constant Pool입니다. 이 곳에는 기존에 만들어진 문자열 값 저장되어 있고, s1, s2처럼 ""로 생성된 같은 값을 가지는 String 객체는 같은 레퍼런스를 가지게 됩니다.
그럼 다시 1번 질문을 보겠습니다.
String str1 = new String("gabbar");
String str2 = new String("gabbar");
String str3 = "gabbar";
str1, str2는 heap 메모리에 개별 객체가 만들어지고, str3는 string constant pool에 객체가 만들어집니다.
그래서 총 3개의 객체가 메모리에 생성되게 됩니다.
System.out.println( str1 == str1.intern() );
System.out.println( str3 == str1.intern() );
그렇다면 intern() 메소드는 어떤 역할을 하고, 위 코드의 결괏값은 어떨까요?
intern() 메소드를 사용하면, Heap 메모리에 있는 String 객체는 String constent pool로 이동합니다.
그래서 str1 == str1.intern()의 결과는 false가 되고, str3==str1.inern()의 결과는 true가 됩니다.
위 질문은 자바의 메모리 관리, 자료형의 특징 등을 알아볼 수 있는 문제였습니다. 때문에 더 많은 공부를 원하시면 아래 링크들을 참고 하사 셔서 공부하시면 좋겠습니다.
- https://ko.wikipedia.org/wiki/%EB%B6%88%EB%B3%80%EA%B0%9D%EC%B2%B4
- http://egloos.zum.com/iilii/v/4427484
앞으로 이 글처럼 개발자 면접 질문들로 나올 수 있는 주제에 대해서 정리하고 공유하는 공간을 브런치를 통해 만들고자 합니다.