String equals() 와 == 의 차이, String Pool

김운채·2023년 5월 5일
0

Java

목록 보기
10/11
post-thumbnail

저번에 String 선언 방법에 따른 차이를 적었었는데, String literal, new String()

이번에 equals()와 == 의 차이를 비교해보려한다.

✅equals()

equals()는 문자열의 내용을 비교하여 같으면 true를 반환하고, 다르면 false를 반환한다. 이때 비교하는 것은 문자열이 가지고 있는 값 자체를 비교한다.

✅==
== 연산자는 두 개의 객체가 동일한 객체인지를 비교한다. 이때 비교하는 것은 객체의 참조값이다. 즉, 두 개의 객체가 동일한 메모리 주소를 가리키고 있는지를 비교한다.


String 에는 두가지 선언방식이있는데,

  • literal 을 이용한 방식 (기본자료형처럼 직접 할당)
  • new 예약어를 이용한 방식 (생성자를 통한 참조형)

Java에서는 String을 저장하는데 2곳의 메모리를 사용할 수 있다. String은 일반적인 Heap에 저장할 수 있고 또한 별도의 String constants Pool이라는 공간을 제공하고 있다.

여기서 String Constant Pool 이게 무엇인지 훑어보자.

String Constant Pool

String literal로 생성하면 해당 String 값은 Heap 영역 내 "String Constant Pool"에 저장되어 재사용되지만, new 연산자로 생성하면 같은 내용이라도 여러 개의 객체가 각각 Heap 영역을 차지하기 때문에 new 연산자로 String 객체를 생성하지 않는 것이 좋다고 한다.

String Pool은 기본적으로 HashMap의 구조이다. String을 hashing하고 그것을 key로 하여 값을 찾기 때문에 String Pool은 좋은 성능을 발휘할 수 있다고 한다.

문자열 리터럴을 사용하여 String 객체를 생성하면 String Pool에 기존에 같은 값을 가지는 String 객체가 있는지 검사하고 있으면 그 객체의 참조값을, 없으면 String Pool에 새로 String 객체를 생성하고 그 참조값을 리턴한다.

이 string pool 은 java 버전이 업데이트 되면서 많은 변화가 있었다.

👉 Java 6 이전

Java 6 이전에서의 Spring Pool은 사실 Heap 메모리에 존재하지 않았다. 바로 PermGen(Permenent Generation)에 있었다. 이 PermGen은 메타 클래스 데이터등을 저장해두는 Method 영역에 있는 메모리이다. 하지만 이 PermGen은 사이즈가 고정(32MB ~ 96MB) 되어있었다. 따라서 너무 많은 String 데이터를 사용한다면 OOM이 발생하곤 했었다.

👉 Java 7 이후

Java 7 버전으로 올라오면서 String Pool은 PermGen이 아닌 Heap 메모리 영역으로 위치를 옮겼다. 그렇기 때문에 java 7 부터는 더이상 고정된 String Pool 메모리 사이즈 때문에 걱정하는 일은 없어졌다. 이제 Heap 사이즈를 조절하면 String Pool도 함께 영향을 받게 된 것.


그럼 이제 == 와 equals 를 사용해 비교해보자

literal 을 이용한 방식

String str1 = "Hello";
String str2 = "Hello";

위와 같이 두개의 string 을 선언하면 JVM은 "Hello"라는 문자열 리터럴을 Heap 메모리 안에 String Constant Pool에 저장하고, str1과 str2가 동시에 "Hello"를 가리키도록 한다.

따라서, str1 == str2 비교 결과는 true가 된다. 하지만 이는 String 객체의 내용이 같은지를 비교하는 것이 아니라, 객체의 참조값이 같은지를 비교하는 것이기 때문에, equals()를 사용하여 내용을 비교하는 것이 좀 더 적절한 방법이다.

new 예약어를 이용한 방식

String strHeap1 = new String("Hello");
String strHeap2 = new String("Hello");

new 연산자를 사용하여 String 객체를 생성하면, 해당 객체는 Heap 메모리 영역에 생성된다. 이때, str은 String Constant Pool이 아닌 Heap 메모리 영역에 생성된 객체를 가리키게 된다.

위 코드에서 strHeap1과 strHeap2는 각각 "Hello" 문자열을 가지는 객체를 생성하게 되며, ==로 비교하면 주소값이 다르므로 false를 반환한다. 이 경우에는 equals() 메소드로 문자열 내용을 비교해야 한다.

String str = 'hi'
Strign str2 = new String("hi")

위 코드에서 == 비교하면 false, eqauls() 로 비교하면 true 가 나오게 된다.

0개의 댓글