1. String 객체의 불변의 원칙
String 문자열은 불변한다.
String ss = "java";
ss = "algo";
Code language: JavaScript (javascript)
”java”는 “algo"로 변하지 않는다.
값이 “java”와 “algo”인 2개의 String 객체를 생성한다.
ss는 참고값만 바꾼다.
ss = ss.toUpperCase();
- toUpperCase() : 모든 소문자를 대문자로 만든 String 객체를 반환한다.
하지만 기존의 객체(ss)는 변하지 않는다.
toUpperCase()가 새로운 문자열을 결괏값으로 반환할 뿐이다.
public class ST {
ST(){
String s = "j";
m1(s);
System.out.println(s);
StringBuilder sb = new StringBuilder("A");
m2(sb);
System.out.println(sb);
}
void m2(StringBuilder sb1) {
sb1.append("G");
}
void m1(String s1) {
s1 = s1.concat("k");
}
public static void main(String[] args) {
new ST();
}
}
/*
j
AG
*/
Code language: JavaScript (javascript)
String만 예외적으로 불변이다.
2. String을 조심해서 사용해야 하는 이유
String s1 = "A";
s1 = s1 + "B";
//complier는 내부적으로 아래와 같이 동작한다.
StringBuilder sb = new StringBuilder(s1);
sb.append("B");
s1 = sb.toString();
Code language: JavaScript (javascript)
자바는 연산자 오버로드가 없기 때문에 특수한 과정을 겪게 된다.
대표적으로 + 하면 컴파일러는 StringBuilder.append()를 호출해서 문자열을 조작한다.
String ss = "A" + 3 + true + 3.2 + "algo";
//혼난다.
Code language: JavaScript (javascript)
만약 위와 같이 코드를 작성하면 컴파일러는 다음과 같이 동작하게 된다.
String ss = new StringBuilder(new StringBuilder(new StringBuilder(new StringBuilder("A").append(3).toString()).append(true).toString()).append(3.2).toString())).append("algo").toString();
//크게 혼난다.
Code language: JavaScript (javascript)
이러한 이유로 자바에서 문자열을 생각 없이 사용하면 메모리 누수가 발생할 수 있다.
StringBuilder sb = new StringBuilder("A").append(3).append(true).append(3.2).append("algo").toString();
//이렇게 하자.
Code language: JavaScript (javascript)
StringBuilder (혹은 멀티 스레드 환경에서는 StringBuffer)를 사용해서 문자열을 가공하자.
jdk 7.0부턴 컴파일러가 알아서 예방해주고 있다고 한다.
String badCase = "A";
for(int i=0; i<100000; i++){
badCase += i;
//badCase = new StringBuilder(sss).append(i).toString();
}
String goodCase = "A";
StringBuilder sb = new StringBuilder(goodCase);
for(int i=0; i<100000; i++) {
sb.append(i);
}
goodCase = sb.toString();
Code language: JavaScript (javascript)
하지만 이와 같은 경우는 여전히 성능 차이가 발생한다.
StringBuilder (혹은 멀티 스레드 환경에서는 StringBuffer)를 사용해서 문자열을 가공하자!
3. 필수 String method
사용할 때마다 하나씩 추가하기
length()toCharArray()charAt()replace()indexOf()lastIndexOf()subString()subSequence()concat()