String, StringBuilder, StringBuffer 클래스 + text block

준우·2022년 4월 21일
0

Java

목록 보기
5/30
post-thumbnail

String 클래스

String 선언

String을 선언하는 방법은 아래와 같이 두가지다.

String str1 = new String("abc"); 
String str2 = "abc"; 
  • str1처럼 힙 메모리에 인스턴스로 생성되는 경우와
  • str2처럼 상수 풀(constant pool)에 있는 주소를 참조하는 방법.
    ("abc" 문자열을 가르키는 변수 str2)
String str1 = new String("abc");
String str2 = new String("abc");		
System.out.println(str1 == str2);//false
	
String str3 = "abc";
String str4 = "abc";
		
System.out.println(str3 == str4); //true

힙 메모리는 생성될 때 마다 다른 주소값을 가진다.
따라서 == 연산자를 사용해 str1과 str2를 비교하면 false 가 나온다.
반면 str3과 str4처럼 상수 풀의 문자열은 모두 같은 주소값을 가진다.

String의 불변성

한번 생성된 String은 불변 immutable 의 특징을 가지고 있다.
예를 들어 concat() 메소드를 사용해서 String 과 String을 연결하면
기존의 문자열에 내용이 추가/연결되는 것이라고 생각하기 쉽지만
사실은 이전 문자열과 다른 아예 새로운 문자열이 생성된다.

public class StringTest {
    public static void main(String[] args) {
        String java = new String("java");
        String android = new String("android");

        System.out.println(System.identityHashCode(java));
        java = java.concat(android);
         
        System.out.println(System.identityHashCode(java));
        System.out.println(java);
    }
}

"Fast"와 "Campus" 문자열을 더하면 "Fast Campus"가 되는듯 싶지만
위 코드처럼identityHashCode() 를 사용해 객체의 고유한 값을 리턴한 결과를 보면
사실은 "Fast Campus"라는 새로운 문자열이 생성된 것이고, 변수는 그것을 가르킬 뿐이라는 것을 알 수 있다.

따라서 이렇게 String 연결을 다건하게 되면 메모리 낭비가 발생할 수도 있다.

그러면 어떻게 해야 하느냐?

이럴 때 사용하기 좋은 것이 StringBuilder, StringBuffer 클래스 이다.

StringBuilder, StringBuffer 클래스

장점

final로 선언된 String과 달리 StringBuilder, StringBuffer는
내부적으로 char[] 를 멤버 변수로 가져 값이 가변적이다.
새로운 인스턴스를 생성하지 않고 char[] 를 변경하는 것이다.
해당 값을 사용할 때는 toString() 메서드로 String 반환을 하면 된다.

이런 특징 때문에 문자열을 여러번 연결하거나 변경할 때
StringBuilder, StringBuffer를 사용하면 유용하다.

차이점

StringBuilder, StringBuffer 모두 char[] 를 멤버 변수로 가졌다는 공통점이 있지만,
StringBuffer는 멀티 쓰레드 프로그래밍에서 동기화(synchronization)을 제공한다는 차이점이 있다. (두개 이상의 쓰레드가 서로 같은 멤버를 Access할 때 순서가 정해진다는 이야기)

따라서 멀티 쓰레드 프로그램에서는 StringBuffer를 사용하고,
단일 쓰레드 프로그램에서는 StringBuilder 사용을 권장한다.

위 String 예제에서 사용한 코드와 동일한 예시로
둘 중 StringBuilder 에 대해 더 자세히 알아보자.

public class StringBuilderTest {
    public static void main(String[] args) {

        String java = new String("java");
        String android = new String("android");

        StringBuilder buffer = new StringBuilder(java);
        System.out.println(System.identityHashCode(buffer));

        buffer.append(android);
        System.out.println(System.identityHashCode(buffer));

        String test = buffer.toString();
        System.out.println(test);
    }
}

String 과 달리, identityHashCode() 를 사용해도 동일한 값이 리턴됨을 알 수 있다.
위 예시처럼 반환 시에는 toString() 을 사용하면 된다.

text block (java 13)

그리고 자바 13 버전에서부터 제공되는 text block 을 사용하면
문자열을 """ """ 사이에 이어서 긴 텍스트를 쉽게 만들 수 있고
html, json 문자열을 만드는데에도 유용하게 사용할 수 있다.


public class TextBlockTest {
    public static void main(String[] args) {
        String textBlock = """
                Hmm... This is text block test
                Interesting. """;

        System.out.println("textBlock = " + textBlock);
        System.out.println(getBlockOfHtml());
    }


    public static String getBlockOfHtml() {
        return """
		            <html>

		                <body>
		                    <span>example text</span>
		                </body>
		            </html>""";

    }
}

0개의 댓글