String class
문자열을 다루기 위해 사용되는 핵심 클래스로, 다음과 같은 주요 특징을 가진다.
문자열은
char배열로 구성되어 있으며,String클래스는char배열을 내부적으로 가지고 있음문자열 리터럴은
String Constant Pool영역에서 효율적으로 관리문자열을 변경하는 메서드는, 원본 객체를 변경하는 것이 아니라 변경된 내용의 새로운
String인스턴스를 생성하여 반환
내부적으로 private final char[] value를 사용하여 문자를 저장으나, 자바 9부터는 private final byte[] value와 coder 필드를 사용하여 메모리 효율성을 높였다.
public final class String implements java.io.Serializable, Comparable<String>, CharSequence {
@Stable
private final byte[] value;
private final byte coder;
// ...
}주요 메서드
charAt(int index)
문자열에서 index 위치의 문자를 반환
int length()
문자열의 길이를 반환
String substring(int from, int to)
문자열에서 해당 범위에 있는 문자열 반환
String substring(int from)
문자열에서 해당 위치부터 끝까지 문자열 반환
String concat(String str)
문자열을 더해서 새로운 문자열 반환
String replace(String old, String new)
문자열에서 old 문자열을 new 문자열로 바꾼 새로운 문자열 반환
String toLowerCase()
문자열을 소문자로 바꾼 새로운 문자열 반환
String toUpperCase()
문자열을 대문자로 바꾼 새로운 문자열 반환
String trim()
문자열의 앞뒤 공백을 제거한 새로운 문자열 반환
String[] split(String regex)
문자열을 regex를 기준으로 나눈 문자열 배열 반환
boolean equals(Object obj)
문자열이 같은지 비교
int compareTo(String str)
문자열을 사전순으로 비교
int indexOf(String str)
문자열에서 str이 처음 나타나는 위치를 반환
boolean startsWith(String prefix)
문자열이 prefix로 시작하는지 확인
boolean endsWith(String suffix)
문자열이 suffix로 끝나는지 확인
boolean contains(String str)
문자열이 str을 포함하는지 확인
boolean isEmpty()
문자열이 비어있는지 확인
char[] toCharArray()
문자열을 문자 배열로 변환
문자열 비교
문자열을 비교하는 방법은 == 연산자를 이용한 주소값 비교와 equals() 메서드를 이용한 내용 비교 두 가지가 있다.
class Example {
public static void main(String[] args) {
String str1 = "ogu"; // 리터럴로 생성
String str2 = "ogu"; // 리터럴로 생성
String str3 = new String("ogu"); // 인스턴스 생성
String str4 = new String("ogu"); // 인스턴스 생성
// == (동일성 비교): 같은 인스턴스(주소)인지 비교
System.out.println(str1 == str2); // true (str1과 str2는 Pool의 동일 인스턴스 참조)
System.out.println(str3 == str4); // false (str3과 str4는 Heap의 서로 다른 인스턴스)
// equals() (동등성 비교): 내용이 같은지 비교
System.out.println(str1.equals(str2)); // true
System.out.println(str1.equals(str3)); // true (내용 "ogu"는 동일)
}
}String 클래스의 equals
String 클래스는 Object 클래스의 equals() 메서드를 재정의(override)하여, 두 문자열의 내용을 비교하도록 구현되어 있다.
// 실제 String 클래스의 equals() 메서드
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String aString = (String) anObject;
if (coder() == aString.coder()) {
return isLatin1() ? StringLatin1.equals(value, aString.value)
: StringUTF16.equals(value, aString.value);
}
}
return false;
}Constant Pool
JVM은 'String Constant Pool'(문자열 상수 풀)이라는 메모리 영역을 가진다.
문자열 리터럴 생성 (
String s1 = "ogu";):String Pool에 "ogu"라는 문자열이 있는지 탐색
존재하면, 기존에 있던 인스턴스의 참조를 반환
존재하지 않으면, 풀(Pool)에 "ogu" 인스턴스를 새로 생성하고 그 참조를 반환
new연산자 생성 (String s3 = new String("ogu");):new연산자는 String Pool과는 별개로, 힙(Heap) 영역에 "ogu" 내용을 가진 새로운String인스턴스를 항상 생성이때 "ogu" 리터럴 자체는 String Pool에도 존재하게 됨
new로 생성된 객체의 참조를 intern() 메서드를 통해 String Pool의 참조로 변경할 수도 있다.
StringBuffer & StringBuilder
String 클래스는 문자열 연산이 빈번하게 발생하면 성능 저하의 원인이 될 수 있어, 문자열을 효율적으로 다루기 위한 StringBuffer와StringBuilder 클래스를 제공한다.
컴파일러 최적화
자바 컴파일러는 문자열 덧셈 연산을 StringBuilder를 사용한 코드로 자동 변환하여, 성능 저하의 문제를 완화한다.
String s = "A" + "B"; // String s = "AB";로 변환
String s1 = str1 + str2; // String s1 = new StringBuilder().append(str1).append(str2).toString();로 변환하지만, 반복문 내에서 문자열 덧셈을 사용할 경우 매 반복마다 StringBuilder가 새로 생성되어 비효율적이므로, 이때는 개발자가 직접 StringBuilder를 생성하여 사용해야 한다.
StringBuffer
내부적으로 문자열 편집을 위한
buffer를 가지고 있음생성자를 통해 초기 용량을 지정할 수 있으며 버퍼의 크기가 부족할 경우 자동으로 증가
메서드 대부분이
synchronized로 선언되어 있어, 멀티스레드 환경에서 안전하게 사용 가능
StringBuffer 문자열 비교
StringBuffer는 equals() 메서드를 재정의하지 않았기 때문에, Object의 equals()가 호출되어 주소값을 비교(==)한다.
public class StringBufferTest {
public static void main(String[] args) {
StringBuffer sb1 = new StringBuffer("ogu");
StringBuffer sb2 = new StringBuffer("ogu");
System.out.println(sb1 == sb2); // false
System.out.println(sb1.equals(sb2)); // false
System.out.println(sb1.toString().equals(sb2.toString())); // true
}
}StringBuilder
thread safe한 StringBuffer와 달리thread unsafe위 기능을 제외하고는 StringBuffer와 동일
String, StringBuffer, StringBuilder 비교
가변성(Mutability)
불변(Immutable)
가변(Mutable)
가변(Mutable)
저장 위치(리터럴)
String Pool
Heap
Heap
스레드 안전성(Thread Safety)
안전(Immutable)
안전(Synchronized)
안전하지 않음
주요 사용 환경
문자열 연산이 적을 때
멀티스레드 환경
단일 스레드 환경
성능(문자열 변경 시)
낮음(새 객체 생성)
높음
매우 높음
참고자료
Last updated
Was this helpful?