본문 바로가기
Language/JAVA

[JAVA] 리터럴 String vs String 객체

by jepa 2023. 8. 22.
728x90
SMALL

목표

문자열을 선언하는 방법에는 String 리터럴과 new String() 두 가지가 있다.

둘의 차이를 알아보자.

 

String 리터럴 값

Java의 문자열 리터럴은 상수로 취급되며, 이러한 문자열들은 JVM 내부의 특정 영역인 상수 풀(String pool)이라고 하는 공유된 메모리 영역에 해당 문자열이 저장됩니다.

 

따라서 동일한 값을 가진 다른 변수가 같은 메모리 위치를 참조하게 되어 메모리를 절약할 수 있습니다.

참고: JAVA7부터 문자열 상수풀 위치가 Perm영역에서 Heap영역으로 옮겨졌다고 한다.

String 객체

새로운 String 객체를 생성합니다.

이렇게 하면 항상 새로운 객체가 만들어지기 때문에, 같은 값의 문자열도 매번 새로운 메모리 공간에 할당됩니다.

즉, 가상 머신 안에서 이와 똑같은 문자열 리터럴을 사용하는 모든 코드는 같은 객체를 재사용함이 보장됩니다.

 

String 리터럴 vs String 객체

코드로 비교해보자.

==: 주소 값을 비교한다
equals: 단순 문자열의 값을 비교한다.
String l1 = "abc";
String l2 = "abc";
String s3 = new String("abc");
String s4 = new String("abc");
String intern = s3.intern(); // abc라는 문자열이 String Constant Pool에 존재하는지 확인
System.out.println(l1 == l2); // true
System.out.println(s3 == s4); // false
System.out.println(l1 == s3); // false
System.out.println(l1 == intern); // true
System.out.println(l1.equals(s3)); // true
System.out.println(s3.equals(s4)); // true

위의 코드를 그림으로 그리면 아래와 같다.

==는 주소를 비교하기 때문에 l1과 l2는 같은 주소값을 가리켜서 true가 나오고

s3 s4는 서로 다른 객체로 생성되었기 때문에 false 가 나온다.

 

반면 equals는 문자열의 값을 비교하기 때문에 모두 true로 나온다.

 

public native String intern();
Java에서 String 객체를 상수 풀(constant pool)에 있는 다른 동일한 문자열과 비교하는 데 사용되는 메소드

intern() 메소드를 호출하면 해당 문자열이 이미 상수 풀에 있는지 확인합니다.
만약 있으면, 기존의 인스턴스를 반환하고 없으면 새로운 인스턴스를 생성하여 상수 풀에 추가하고 그 참조도 반환합니다.

주요 용도 중 하나는 문자열 비교 성능을 최적화하는 것입니다. 예를 들어, 많은 수의 동일한 값을 가진 String 객체가 있다고 가정해봅시다. 각각의 객체마다 일일히 비교하는 대신, intern()을 사용하여 같은 값을 공유하는 하나의 인스턴스만 유지할 수 있습니다.

String(String original)를 사용해야하는 경우가 있을까?

일반적인 상황에서는 해당 생성자를 사용할 필요가 없습니다.

해당 생성자는 문자열을 복제하는 용도로 사용될 수 있지만, 일반적으로 문자열은 이미 자체적으로 불변성(immutable)을 가지고 있기 때문에 추가적인 복제 작업이 필요하지 않습니다.

 

new String(String str) 생성자를 사용하면 기존의 문자열을 복제하여 새로운 인스턴스를 만드는 것입니다.

하지만 이렇게 하면 메모리 낭비가 발생하고 성능 저하도 초래될 수 있습니다.

 

따라서 대부분의 경우, 기존의 문자열 변수나 리터럴을 직접 사용하는 것이 바람직합니다.

실제로 값이 변경되어야 할 때만 new String() 생성자를 사용해야 합니다.

 

 

참고 블로그 https://madplay.github.io/post/java-string-literal-vs-string-object

 

자바의 String 객체와 String 리터럴

자바에서 문자열을 선언하는 방법은 두 가지가 있다. String과 new String()은 어떤 차이가 있을까?

madplay.github.io

 

728x90
LIST