Post

Java 문자열 초기화

1. Creation

Java에서 String이 생성되는 방식을 알아야 한다.

new 키워드나 리터럴 구문을 사용할 수 있다.

1
2
String usingNew = new String("baeldung");
String usingLiteral = "baeldung";

2. 문자열 선언만

명시적으로 값을 할당하지 않고 String을 선언한다.

로컬 또는 멤버 변수로 이 작업을 수행할 수 있다.

1
2
3
4
5
6
7
8
9
10
11
public class StringInitialization {

    String fieldString;

    void printDeclaredOnlyString() {
        String localVarString;
        
        // System.out.println(localVarString); -> compilation error
        System.out.println(fieldString);
    }
}

값을 지정하기 전에 localVarString을 사용하려고 하면 컴파일 오류가 발생한다. 반면에 콘솔은 fieldString의 값 에 대해 “null” 을 표시한다.

멤버 변수는 클래스가 생성될 때 기본값으로 초기화되며 String의 경우 null 이다. 그러나 지역 변수를 직접 초기화해야 한다.

localVarString에 null 값 을 지정하면 두 값이 실제로 동일하다는 것을 알 수 있다.

1
2
String localVarString = null;
assertEquals(fieldString, localVarString);

3. 리터럴을 사용한 문자열 초기화

동일한 리터럴을 사용하여 두 개의 String을 생성한다.

1
2
String literalOne = "Baeldung";
String literalTwo = "Baeldung";

참조를 비교하여 하나의 객체만 생성되었는지 확인한다.

1
assertTrue(literalOne == literalTwo);

그 이유는 String이 풀에 저장 된다는 사실과 관련이 있다. literalOne은 풀에 “baeldung” 문자열을 추가하고 literalTwo는 이를 재사용한다.

4. new를 사용한 문자열 초기화

그러나 new 키워드를 사용하면 몇 가지 다른 동작을 볼 수 있다.

1
2
String newStringOne = new String("Baeldung");
String newStringTwo = new String("Baeldung");

두 String의 값은 이전과 동일하지만 이번에는 다른 객체를 지정해야 한다.

1
assertFalse(newStringOne == newStringTwo);

5. 빈 문자열

세 개의 빈 String을 생성한다.

1
2
3
String emptyLiteral = "";
String emptyNewString = new String("");
String emptyNewStringTwo = new String();

지금까지 알고 있는 것처럼 emptyLiteral은 String pool에 추가되고 나머지 두 개는 힙에 직접 추가된다.

이들은 동일한 객체가 아니지만 모두 동일한 값을 갖는다.

1
2
3
4
5
assertFalse(emptyLiteral == emptyNewString)
assertFalse(emptyLiteral == emptyNewStringTwo)
assertFalse(emptyNewString == emptyNewStringTwo)
assertEquals(emptyLiteral, emptyNewString);
assertEquals(emptyNewString, emptyNewStringTwo);

6. null 값

null String의 작동 방식이다.

null String을 선언하고 초기화한다.

1
String nullValue = null;

nullValue를 인쇄하면 이전에 본 것처럼 “null”이라는 단어가 표시된다. 그리고 nullValue에 대한 메서드를 호출하려고 하면 NullPointerException이 발생한다.

JVM 사양은 null이 모든 참조에 대한 기본값이라고 말하므로 특별히 String에 연결되지 않는다. 그리고 실제로 사양은 null에 대한 구체적인 값 인코딩을 요구하지 않는다.

그렇다면 String을 인쇄하기 위해 “null”은 어디에서 온것인가?

PrintStream#println 구현을 살펴보면 String#valueOf를 호출하는 것을 볼 수 있다.

1
2
3
4
5
6
7
public void println(Object x) {
    String s = String.valueOf(x);
    synchronized (this) {
        print(s);
        newLine();
    }
}

그리고 String#valueOf를 보면 다음과 같은 답을 얻을 수 있다.

1
2
3
public static String valueOf(Object obj) {
    return (obj == null) ? "null" : obj.toString();
}

이것이 “null”의 이유이다.

[출처 및 참고]

This post is licensed under CC BY 4.0 by the author.