참조 및 직접 찾아봄
- String 객체는 불변이기 때문에 변하지 않는 문자열은 String을 사용한다.
- StringBuilder는 비동기방식이기 때문에 Single Thread 환경하에서, 변화되는 문자열의 사용한다.
- StringBuffer 동기방식으로 저장되기 때문에 멀티쓰레드로 접근하거나 문자열이 변경될 경우에 사용한다.
“string”.concat(“sum”);
1.8 버전에서 확인
concat 함수는 내부에서 문자열을 합친 후
new String(합친 문자열)
새로운 스트링을 반환함String concatTest = "s".concat("s").concat("s");
형태로 사용 가능 문자열 자체는 Java에서불변(immutable)
으로 다루고 있음
그렇다면 “스트링” + “스트링”은 어떻게 동작할까?
- 연산은 내부적으로 스트링 빌더를 사용해 문자열을 붙여 toString으로 리턴한다.
String example = "스트링" + "스트링2";
String real = new StringBuilder(String.valueOf("스트링")).append("스트링2").toString(); // +연산자 실제 동작방식
"".concat과 StringBuilder의 차이는?
- 효율성? 문제.
- concat은 새로운 new String을 만들어 반환하는 형태이기 때문에, 새로운 String을 담을 공간이 필요함.
- 실제 함수를 타고 들어가보면 concat은 new String을 반환하고, append는 기존 메모리의 캐릭터 시퀀스 뒤에 갖다 붙이는걸 볼 수 있음
/** String 객체에서 사용할 수 있는 concat 메소드 **/
/** Java 1.8 **/
public String concat(String str) {
int otherLen = str.length();
if (otherLen == 0) {
return this;
}
int len = value.length;
char buf[] = Arrays.copyOf(value, len + otherLen);
str.getChars(buf, len);
return new String(buf, true);
}
주소 | 값 |
---|---|
0x00 | 하나 |
0x01 | 하나둘 |
0x02 | 하나둘셋 |
0x03 | 하나둘셋넷 |
/** StringBuilder가 상속받는 추상 클래스의 append 메소드 **/
/** Java 1.8 **/
public AbstractStringBuilder append(String str) {
if (str == null)
return appendNull();
int len = str.length();
ensureCapacityInternal(count + len);
str.getChars(0, len, value, count);
count += len;
return this;
}
주소 | 값 |
---|---|
0x00 | 하나 |
0x00 | 하나둘 |
0x00 | 하나둘셋 |
0x00 | 하나둘셋넷 |
StringBuffer와 StringBuilder?
- 두개 다 똑같이 AbstractStringBuilder 추상 클래스를 상속받고 있음.
- 즉, append 메소드는 동일함
- 그러나 StringBuffer는 synchronized 키워드로 멀티스레드 환경에서 안정성을 확보하고 있음
- StringBuilder는 키워드 없음!
/** StringBuffer의 append **/
/** synchronized 키워드 확인 **/
@Override
public synchronized StringBuffer append(String str) {
toStringCache = null;
super.append(str);
return this;
}
/** StringBuffer의 append **/
/** synchronized 키워드는 없음 **/
@Override
public StringBuilder append(String str) {
super.append(str);
return this;
}
끝으로
추측
하지 말고증명
하자의 실천!