String str1 = new String("abc");
String str2 = "abc";
위의 코드는 String class를 만드는 두가지 방법을 나타낸다. 두가지 방법은 보기에는 같은 결과가 나온다고 생각할 수 있지만 내부적으로는 다른 결과를 낸다.
str1의 경우는 new String을 사용하여 힙 메모리에 새로운 인스턴스를 생성이 된다. 반면에 str2의 경우는 상수 풀(constant pool)의 "abc"의 address만 가르키기만 한다.
public class StringTest {
public static void main(String[] args) {
String str1 = new String("abc");
String str2 = new String("abc");
System.out.println(str1 == str2);
String str3 = "abc";
String str4 = "abc";
System.out.println(str3 == str4);
}
}
그리하여 위의 코드의 경우 new String을 사용하여 새로운 인스턴스를 생성한 str1, str2의
경우는 서로 다른 주소값을 가르키지만 상수풀의 주소만을 가르키며 생성한 str3, str4의 경우는 값이 같다는 결과가 나오게 된다.
String은 final로 만들어져 인스턴스의 값은 한번 생성하면 변경이 불가능하다. 그래서 concat과 같은 문자열 변환 코드를 사용하여 string의 값을 변경하려고 한다면 기존 인스턴스는 남아있고 남아있는 기존 인스턴스를 사용하여 새로운 인스턴스를 만들게 되어 메모리 낭비가 발생한다.
-> string변환을 할 경우 기존 인스턴스 변환이 아닌 새로운 인스턴스가 생겨난다.
-> 메모리 낭비가 발생하기에 StringBuilder, StringBuffer를 사용해야한다.
둘 다 내부적으로 가변적인 char[]를 멤버 변수로 가진다.
새로운 인스턴스를 생성하지 않고 char[]를 변경할 수 있어서 문자열을 여러번 연결하거나 변경할 때 사용하면 유용하다.
출력은 나중에 toString() 메서드로 String반환을 해주면 된다.
StringBuilder와 StringBuffer는 char[] (character buffer)를 갖는 공통점이 있으나 StringBuffer는 multi-thread환경에서 동기화(synchronization)가 보장된다. (두개 이상의 thead가 작업을 할 때 순서를 정해준다.)
그래서 single thread 프로그래밍의 경우는 StringBuilder사용을 권장하며 multi-thread환경에서는 StringBuffer를 사용을 권장한다.
package ch03;
public class StringBuilderTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
String java = new String("java");
String android = new String("android");
StringBuilder buffer = new StringBuilder(java); //java를 넣은 string buffer생성
System.out.println(System.identityHashCode(buffer));
buffer.append(android); //java가 들어있는 buffer에 android를 추가러 넣어준다.
System.out.println(System.identityHashCode(buffer));
//위의 buffer hashcode출력 결과와 같은 결과가 나옴
String test = buffer.toString(); // 연결을 마치고 toString으로 결과 return
System.out.println(test);
}
}
서버에서 클라이언트로 data를 response할때 테그와 데이터를 다 넣으려면 지저분 할 수 있는데 이런 경우 text block을 사용하면 깔끔하게 볼 수 있다. (html, json 문자열을 만드는데 유용하게 사용할 수 있다.)
java13부터 지원된다.
package ch03;
public class TextBlockTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
// """사이에 쓰고 싶은대로 쓰면 된다.(줄바꿈도 다 적용된다.)
String strBlock = """
This
is
text
block
test.""";
System.out.println(strBlock);
System.out.println(getBlockOfHtml());
}
// html도 쉽게 사용가능하다.
public static String getBlockOfHtml() {
return """
<html>
<body>
<span>example text</span>
</body>
</html>""";
}
}