Java(2) 문자열 비교하기
1. 문자열 비교하기
(1) ==, !=
- 문자열의 일치 여부가 아닌, 문자열 객체가 위치하는 주소값을 비교한다.
- cf. 문자열은 ==, != 비교는 가능하지만 대소 비교는 불가능하다.
(2) 문자열1.equals(문자열2)
- 문자열1과 문자열2의 값을 비교
2. Java에서 String을 생성하는 2가지 방법
1. 리터럴을 이용하는 방법
- 리터럴을 이용해 같은 문자열을 할당해주면 두 String 변수는 동일한 메모리 위치를 참조한다.
// str1과 str2은 동일한 메모리 위치 참조
String str1 = "java";
String str2 = "java";
2. new 연산자를 이용하는 방법
String str = new String("java");
// str은 str1, str2와 다른 메모리 주소를 참조한다.
(1) 리터럴을 이용하는 방법 VS new 연산자를 이용하는 방법
- new 연산자를 통해 String을 생성하게 되면
String은 Heap영역에 존재하지만,
리터럴을 이용할 경우 string constant pool이라는 영역에 존재하게 된다.
- String 리터럴이 생성될 때 자바는 동일한 문자열이 이미 string constant pool에 존재하는지를 확인하고,
만약 존재한다면 기존 문자열의 참조를 재사용한다.
- String constant pool은 원래 Perm(= Permanent Heap = PermGen) 영역에 존재했는데,
Java7에서 Heap 영역으로 변경되었다.
Perm 영역의 사이즈는 고정되어 있어서 String 값이 커지면 OutOfMemoryException 문제가 발생할 수 있기 때문이다.
- Heap 영역으로 string constant pool의 위치를 변경하게 되면서,
string constant pool의 모든 문자열도 GC(Garbage Collection)의 대상이 될 수 있게 되었다.
(2) intern()의 사용
- intern() 메서드는 String constant pool에서 리터럴 문자열이 존재하는지 체크한 뒤,
존재한다면 해당 문자열을 반환하고 아니면 리터럴을 String pool에 넣어준다.
// c를 보면, b의 값인 "java"가 이미 string constant pool에 존재하므로 해당 문자열을 반환해서 c는 "java" 가 된다.
// 결국 a와 c는 같은 주소를 참조하게 되어 a == c가 true가 된다.
String a = "java";
String b = new String("java");
String c = b.intern();
System.out.println(a == b); // false
System.out.println(a == c); // true
<참고>
Java String 의 메모리에 대한 고찰
Java 언어에서 String은 무심코 사용되는 클래스 중에 하나가 아닐까 생각이 든다. String은 두 가지 생성 방식이 있고 각각의 차이점이 존재한다.
medium.com