String, StringBuilder, StringBuffer, text block

Bill·2023년 5월 11일
2
post-thumbnail

본 포스트는 카카오 테크 캠퍼스 1기에서 제공하는 패스트캠퍼스 강의에서 배운 내용을 토대로 정리하였습니다.

카카오 테크 캠퍼스

String 클래스


String 선언하기

힙 메모리에 인스턴스로 생성되는 경우와 상수 풀(constant pool)에 있는 주소를 참조하는 두 가지 방법이 있다.

String str1 = new String("abc"); //인스턴스로 생성
String str2 = "abc"; //상수 풀(constant pool)에 있는 주소를 참조

힙 메모리는 생성될때마다 다른 주소 값을 가지지만, 상수 풀의 문자열은 모두 같은 주소 값을 가짐

public class StringTest {

	public static void main(String[] args) {
		String str1 = new String("abc");
		String str2 = new String("abc");

		System.out.println(str1 == str2);//false
		System.out.println(System.identityHashCode(str1));//2055281021
		System.out.println(System.identityHashCode(str2));//1554547125
        //즉 해쉬코드가 다르므로 생성될때 마다 서로 다른 주소를 가짐을 확인 가능.
        
		String str3 = "abc";
		String str4 = "abc";
		
		System.out.println(str3 == str4);//true
        System.out.println(System.identityHashCode(str3));//617901222
		System.out.println(System.identityHashCode(str4)); //617901222
		//즉 해쉬코드가 같으므로 상수 풀의 문자열은 모두 같은 주소값을 가짐 
	}
}

왜그런지 알려면, 상수 풀이 무엇인지 알아야한다.

String Constant Pool

  • String literal로 생성한 객체는 "String Constant Pool"에 들어간다.

  • "String Constant Pool"은 Heap 영역 내 존재한다.

  • new 연산자로 생성한 String 객체는 같은 값이 String Pool에 이미 존재하더라도, Heap 영역 내 별도의 객체를 가리키게 된다.

즉,

자바에서 String 자료형 변수를 String literal로 생성하면 해당 String 값은 Heap 영역 내 "String Constant Pool"에 저장되어 재사용되지만,

new 연산자로 생성하면 같은 내용이라도 여러 개의 객체가 각각 Heap 영역을 차지한다. => 일반적인 객체의 동적할당 과정과 동일.

String literal로 생성한 객체의 값(위그림에선 "Cat")이 이미 String Pool에 존재한다면, 해당 변수는 String Pool의 메모리 주소를 참조한다.

위 그림에서 변수 s1과 s2가 같은 곳을 가리키고 있는 것도 이 때문이다.

문자열 합치기

  • 한번 생성된 String은 불변(immutable)하다

  • String을 연결하면 기존의 String에 연결되는 것이 아닌 새로운 문자열이 생성됨 ( 메모리 낭비가 발생할 수 있다.)

public class StringTest2 {

	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));
		//java변수의 해쉬코드와, 거기에 android를 이어붙인 변수의 해쉬코드는 다르다.
	}
}

StringBuilder, StringBuffer


  • 내부적으로 가변적인 char[]를 멤버 변수로 가짐
  • 문자열을 여러번 연결하거나 변경할 때 사용하면 유용함
  • 새로운 인스턴스를 생성하지 않고 char[] 를 변경함

  • StringBuffer는 멀티 쓰레드 프로그래밍에서 동기화(synchronization)을 보장 => 공유자원 동시접근시, 순서가 정해짐

  • 단일 쓰레드 프로그램에서는 StringBuilder 사용을 권장

  • toString() 메서드로 String반환

public class StringBuilderTest {
//StringBuffer도 문법이 똑같음.
//StringBuffer buffer = new StringBuffer(java);

	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));
		//출력한 두 해쉬코드는 동일한 16진수를 출력함
		java = buffer.toString();
	}
}

text block(after Java 15)


Java 15부터는 """ (큰따옴표 3개)로 시작하여 그 뒤에 선택적 공백과 줄 바꿈이 오는 텍스트 블록을 사용할 수 있다.

html, json 문자열을 만드는데 유용하게 사용할 수 있음

public class StringTextBlock {

	public static void main(String[] args) {
		
		String strBlock = """
				This 
				is 
				text
				block
				test.""";
		System.out.println(strBlock);
		
		System.out.println(getBlockOfHtml());
		
	}
	
	public static String getBlockOfHtml() {
		    return """
		            <html>

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

}
profile
새로운 여정은 언제나 두렵고 동시에 흥미로 가득 차 있다.

0개의 댓글