개요
시간도 있겠다. 이제 하나하나식 참조 자료형(Reference Data Type)에 대해 정리해볼 생각이다. 먼저 String 클래스에 대해 정리해보겠다.
1. String 이란?
String은 Java에서 문자열을 표현하는 불변의 객체이다.
즉, 객체가 한 번 생성된다면 그 값이 변경될 수 없다는 것을 의미한다.
String str = "Hello";
str = str + " World";
str이라는 객체에 " World"를 덧붙이려는 연산을 수행했을 때, 기존 str의 값을 변경하는 것이 아니라
새로운 String 객체 "Hello World"를 생성한 뒤 str 변수가 이를 참조하게 된다.
즉, 이전의 "Hello" 객체는 변경되지 않고 메모리에 그대로 남아있게 되고, 가비지 컬렉터에 의해서 회수된다.
2. String 특징
1) 스레드 안전
-> 불변 객체는 동시에 여러 스레드에서 접근하더라도 객체 자체가 변경되지 않기 때문에 별도의 동기화 없이 안전하게 사용할 수 있다.
2) 캐싱과 재사용
-> 자바에서 문자열 상수 풀(String Constant Pool)이라는 메커니즘을 통해 동일한 문자열 리터럴을 재사용한다.
*리터럴(Literal) : 데이터(값) 그 자체를 의미
-> JVM의 Heap 영역에는 String Constant Pool이 존재하는데 String을 리터럴로 생성할 경우 이 영역에 저장되어서 재사용할 수 있다. 반면, new 연산자로 생성할 경우 일반적인 Heap 영역에 생성돼 재사용할 수 없다.
@Test
public void test() {
String st1 = "Hi";
String st2 = "Hi";
assertSame(st1, st2);
}
@Test
public void test2() {
String st1 = new String("Hi");
String st2 = new String("Hi");
assertSame(st1, st2);
}
위의 코드에서 test는 같고, test2는 같지 않다고 나온다!
*assertSame은 두 변수의 참조 값이 같은지에 대한 여부를 나타낸다.
-> 그렇기에 같은 내용의 문자열의 경우 매번 새로 생성하지 않고 풀에서 가져와 메모리 사용량을 줄이고 성능을 최적화할 수 있다.
3. String 연산 처리
문자열 결합에 + 연산자를 사용하거나 concat() 메서드를 사용할 수 있다. 하지만 위에 언급한 것처럼 String은 불변으로 매번 새로운 String 객체를 새성하는 것은 매우 비효율적이다.
String result = "";
for (int i = 0; i < 1000; i++) {
result += i; // 매번 새로운 String 객체 생성
}
3-1. StringBuffer 및 StringBuilder
그래서 대규모 문자열 연산이나 반복적인 문자열 덧붙이기 작업을 효율적으로 처리하기 위해 StringBuffer나 StringBuilder를 사용한다.
얘네는 문자열을 더하는 과정에서 매번 새로운 객체를 생성하지 않고 내부 버퍼를 이용하기 때문에 대량의 문자열 결합 작업에서 높은 성능을 발휘한다.
StringBuffer
-> 문자열을 변경 가능한 객체로, 내부적으로 synchronized 키워드를 통해 스레드 안정성을 보장한다.
StringBuilder
-> 변경 가능한 객체지만, 스레드 안정성보장을 위한 동기화 처리가 없어 단일 스레드 환경이나 동기화를 필요로 하지 않을 때 사용한다면 빠른 성능을 기대할 수 있다.
4. String 메서드
length()
-> 문자열 길이를 반환한다.
String hello = "Hello World";
int length = hello.length(); // length = 11
charAt(int index)
-> 특정 인덱스에 위치한 문자를 반환한다.
char c = hello.charAt(0); // 'H'
substring(int beginIndex, int endIndex)
-> 부분 문자열을 추출한다.
String sub = hello.substring(0, 5); // "Hello"
toUpperCase() & toLowerCase()
-> 문자열을 대문자 및 소문자로 변환한다.
String upper = hello.toUpperCase(); // "HELLO WORLD"
trim()
-> 문자열 앞 뒤 공백을 제거한다.
String trim = " Java ".trim(); // "Java"
replace()
-> 특정 문자나 문자열을 다른 문자나 문자열로 교체한다.
String replaced = hello.replace("World", "Java"); // "Hello Java"
equals()
-> 실제 문자열 값 비교에 사용된다.
* '==' 연산잔의 경우에는 문자열 리터럴에 대한 참조 비교이다.
'Language > java' 카테고리의 다른 글
[Java] HashMap이란 (0) | 2024.12.16 |
---|---|
[Java] ArrayList란 (0) | 2024.12.13 |
[Java] 자료형 개요 & 숫자 (0) | 2024.01.24 |
[Java] 자바 시작하기 (2) | 2024.01.11 |