일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
- git 기초
- null/not null
- 피연산자
- SQL
- N+1
- 변수와 메서드
- 오버로딩
- 참조타입
- foreigen key
- 지연로딩
- bufferedInputStream
- 추상메서드
- 즉시로딩
- 오버라이딩
- Java
- 변수와 상수
- InterruptedException
- 서버 스크립트
- 프로그래머스 코테
- 원시타입
- 멱등성
- delete
- Shared Lock
- 연산자와의 관계
- 프로그래머스
- jsoup
- 컬렉션 프레임워크
- exclusive lock
- 메세지 큐
- select
- Today
- Total
[JAVA_Back-End]
String / StringBuilder / StringBuffer 본문
String
- immutable(불변)하여 간단하게 사용이 가능하다.
- 동기화에 대해 신경쓰지 않아도 된다. Thread-safe하다. (= 내부 데이터를 자유롭게 공유 가능하다)
- String 객체는 한번 생성되면 할당된 메모리 공간이 변하지 않는다.
+연산자 또는 concat 메서드를 통해 기존에 생성된 String 클래스 객체 문자열에 다른 문자열을 붙여도 기존 문자열에 새로운 문자열을 붙이는 게 아님.
-> 새로운 String 객체를 만든 후, 새 String 객체에 연결된 문자열을 저장, 그 객체를 참조하도록 함
-> String 클래스 객체는 Heap 메모리 영역(가비지 컬렉션이 동작하는 영역)에 생성된다. 따라서 한 번 생성된 내부 내용을 변화시킬 수 없다.
-> 기존 객체가 제거되면 JAVA의 GC가 회수한다.
=> 문자열 연산이 많은 경우 성능이 안좋다.
StringBuffer / StringBuilder
- mutable(가변)하다.
- StringBuffer은 내부적으로 문자열 편집을 위한 buffer를 가지고 있다.
- StringBuffer 인스턴스를 생성할 때 그 크기를 지정할 수 있다.
- 문자열 연산 등으로 기존 객체의 공간이 부족하게 되는 경우, 기존의 버퍼 크기를 늘리며 유연하게 동작한다.
- StringBuffer과 StringBuilder의 차이는 동기화 여부에 있다.
- StringBuffer는 각 메서드별로 Synchronized Keyword가 존재한다.
- StringBuffer는 멀티스레드 환경에서도 동기화를 지원한다.
- StringBuffer는 멀티스레드에 안전(thread safe)하도록 동기화 되어있다.
- StringBuilder는 동기화를 보장하지 않는다.
멀티스레드 환경 => 값 동기화 보장을 위해 StringBuffer를 사용
단일스레드 환경 => StringBuilder을 사용 (StringBuffer은 동기화 관련 처리로 인해 성능이 좋지 않다.)
+) StringBuffer클래스
public final class StringBuffer implements java.io.Serializable{
private char[ ] value; // 문자열을 저장하고 편집하기 위한 buffer
. . .
}
- StringBuffer클래스는 String클래스와 유사한 점이 많다. StringBuffer클래스는 String클래스와 같이 문자열을 저장하기 위한 char형 배열의 참조변수를 인스턴스 변수로 선언해 놓고 있다.
- StringBuffer 인스턴스가 생성될 때, char형 배열이 생성되며 이 때 생성된 char형 배열을 인스턴스변수 value가 참조함.
public StringBuffer(int length){
value = new char[length];
shared = false;
}
public StringBuffer(){
this(16); //버퍼의 크기를 지정하지 않으면 버퍼의 크기는 16이 된다.
}
public StringBuffer(String str){
this(str.length() + 16); //지정한 문자열의 길이보다 16이 더 크게 버퍼를 생성한다.
append(str);
}
- StringBuffer인스턴스에 저장될 문자열의 길이를 고려하여 충분히 여유있는 크기로 지정하는 것이 좋다.
StringBuffer의 내부적인 버퍼크기 변경
- StringBuffer인스턴스로 문자열을 다루는 작업을 할 때, 버퍼의 크기가 작업하려는 문자열의 길이보다 작을 때는 내부적으로 버퍼의 크기를 증가시키는 작업이 수행된다.
- 배열의 길이는 변경될 수 없으므로 새로운 길이의 배열을 생성한 후에 이전 배열의 값을 복사해야 한다.
//새로운 길이(newCapacity)의 배열을 생성한다. newCapacity는 정수값이다.
char newValue[] = new char[newCapacity];
//배열 value의 내용을 배열 newValue로 복사한다.
System.arraycopy(value, 0, newValue, 0, count); // count는 문자열의 길이
value = newValue; //새로 생성된 배열의 주소를 참조변수 value에 저장.
-> 해당 방식으로 StringBuffer클래스의 인스턴스변수 value는 길이가 증가된 새로운 배열을 참조하게 된다.
StringBuffer의 내용 변경
StringBuffer sb = new StringBuffer("abc");
sb.append("123"); //sb내용 뒤에 123 추가
//append는 반환타입이 StringBuffer이다.(자신의 주소 반환)
StringBuffer sb2 = sb.append("ZZ"); //sb의 내용 뒤에 ZZ를 추가
System.out.println(sb); //abc123ZZ
System.out.println(sb2); //abc123ZZ
- sb에 새로운 문자열이 append로 추가되고 sb자신의 주소를 반환하기 때문에 sb2에는 sb의 주소가 저장된다.
- sb와 sb2가 모두 같은 StringBuffer인스턴스를 가리키고 있으므로 같은 내용이 출력된다.
- 따라서 연속적으로 append()를 호출할 수 있다.
StringBuffer sb = new StringBuffer("abc");
sb.append("123").append("ZZ"); // == sb.append("ZZ");
- 이처럼 StringBuffer클래스에는 append()처럼 객체 자신을 반환하는 메서드들이 많다.
정리
String => 짧은 문자열을 더할 경우 사용
StringBuffer => 스레드에 안전한 프로그램이 필요할 때나, 개발 중인 시스템의 부분이 스레드에 안전한지 모를 경우 사용
StringBuilder => 스레드에 안전한지 여부가 전혀 관계 없는 프로그램을 개발할 때 사용하면 좋음
연산이 많은 경우 StringBuilder>StringBuffer>>>String순으로 사용하면 된다.
출처
'Programming > JAVA' 카테고리의 다른 글
객체 지향 프로그래밍(OOP) (1) | 2024.02.13 |
---|---|
JAVA의 타입 (0) | 2024.02.13 |
클래스 / 객체 / 정적(Static) (1) | 2024.02.13 |
[JAVA] 인터페이스 / 추상 클래스 (0) | 2024.02.10 |
어노테이션 / 오버라이딩 및 오버로딩 (0) | 2024.02.07 |