Java

Java(2) 문자열 비교하기

hyomee2 2024. 8. 5. 20:31

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

 

 

 

 

<참고>

1. https://medium.com/@joongwon/string-%EC%9D%98-%EB%A9%94%EB%AA%A8%EB%A6%AC%EC%97%90-%EB%8C%80%ED%95%9C-%EA%B3%A0%EC%B0%B0-57af94cbb6bc

 

Java String 의 메모리에 대한 고찰

Java 언어에서 String은 무심코 사용되는 클래스 중에 하나가 아닐까 생각이 든다. String은 두 가지 생성 방식이 있고 각각의 차이점이 존재한다.

medium.com