String 객체의 데이터가 변하는 경우
데이터가 추가되면, 기존 메모리 공간에 있던 값을 복사해서 새로운 메모리 공간에 할당하고, 추가된 새로운 값들을 뒤에 할당시킨다.
그러고 레퍼런스는 새롭게 만들어진 그 객체를 가리킨다.
문자열이 변경되면 기존의 객체를 버리고, 새로운 객체를 메모리에 생성한다. 이때, 기존 객체는 GC에 의해서 메모리 회수가 이루어진다.
예를들어 이런 문자열이 있을 때
String str = "JAVA'" ;
이 문자열에 요소를 추가하면
str = str + "_8" ;
기존에 있던 객체를 활용하는 것이 아니라,
객체 "JAVA" 를 복사해서 새로운 공간에 객체 "JAVA" 를 하나 만든다.
그러고나서 추가한 문자열 "_8" 이 뒤에 따라와서
새로운 객체 " JAVA_8" 이 만들어진다.
객체 "JAVA" 를 가리키던 기존 레퍼런스는 새롭게 객체 "JAVA_8" 을 가리키게 된다.
String 클래스의 단점을 보완한 클래스
데이터가 변경되면 새로운 객체를 사용하지 않고, 메모리에서 기존 객체를 재활용한다.
속도는 StringBuilder 가 조금 더 빠르며, 데이터 안정성은 StringBuffer 가 더 빠르다.
두 클래스의 사용법은 동일하다. 메소드도 거의 다 동일함.
예를들어 아래와 같은 StringBuffer 객체 "JAVA" 에 "-8" 를 추가하면
StringBuffer sf = new StringBuffer("JAVA");
sf.append("_8");
"JAVA" 라는 값을 일일이 복사하여 새로운 객체를 생성하는 것이 아니라,
기존 객체에 "_8" 를 추가하면 끝이다.
값의 복사가 일어나지 않아서 속도가 빠르다.
StringBuffer sf = new StringBuffer("JAVA");
// append 메소드
sf.append(" World");
System.out.println("sf" + sf); // JAVA World
// length 메소드
System.out.println("sf.length():" + sf.length()); // 10
// delete 메소드
sf.delete(4,8); // 인덱스 4부터 8까지 삭제
System.out.println("sf" + sf); // JAVAd
// StringBuilder 객체
StringBuilder sb = new StringBuilder("JAVA World!");
System.out.println("sb:" + sb);