1. 序章

Java 文字列は最も重要なクラスの1つであり、文字列関連の一連のチュートリアルでその多くの側面をすでに説明しました。

このチュートリアルでは、JavaでのStringの初期化に焦点を当てます。

2. 創造

まず、JavaでStringがどのように作成されるかを覚えておく必要があります。

newキーワードまたはリテラル構文を使用できます。

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

また、文字列が特殊なプールでどのように管理されるかを理解することも重要です。

3. 文字列宣言のみ

まず、値を明示的に割り当てずに、文字列を宣言します。

これは、ローカルで実行することも、メンバー変数として実行することもできます。

public class StringInitialization {

    String fieldString;

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

ご覧のとおり、値を指定する前に localVarString を使用しようとすると、コンパイルエラーが発生します。 一方、コンソールには、fieldStringの値に「null」が表示されます。

メンバー変数は、クラスの構築時にデフォルト値で初期化されます。Stringの場合はnullです。 ただし、ローカル変数を自分で初期化する必要があります。

localVarStringnullの値を指定すると、2つが実際に等しいことがわかります。

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

4. 文字列リテラルを使用した初期化

同じリテラルを使用して2つのStringを作成しましょう。

String literalOne = "Baeldung";
String literalTwo = "Baeldung";

参照を比較して、1つのオブジェクトのみが作成されていることを確認します。

assertTrue(literalOne == literalTwo);

この理由は、文字列がプールに格納されているという事実を思い起こさせます。 literalOneは文字列「baeldung」をプールに追加し、literalTwoはそれを再利用します。

5. String newを使用した初期化

ただし、新しいキーワードを使用すると、いくつかの異なる動作が見られます。

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

両方のStringの値は以前と同じになりますが、今回は異なるオブジェクトにする必要があります。

assertFalse(newStringOne == newStringTwo);

6. 空の文字列

次に、3つの空のStringを作成しましょう。

String emptyLiteral = "";
String emptyNewString = new String("");
String emptyNewStringTwo = new String();

これまでにわかっているように、 emptyLiteralは文字列プールに追加され、他の2つは直接ヒープに追加されます。

これらのは同じオブジェクトではありませんが、すべて同じ値になります。

assertFalse(emptyLiteral == emptyNewString)
assertFalse(emptyLiteral == emptyNewStringTwo)
assertFalse(emptyNewString == emptyNewStringTwo)
assertEquals(emptyLiteral, emptyNewString);
assertEquals(emptyNewString, emptyNewStringTwo);

7. null

最後に、null Stringがどのように動作するかを見てみましょう。

null Stringを宣言して初期化しましょう。

String nullValue = null;

nullValue を出力すると、前に見たように「null」という単語が表示されます。 また、 nullValueでメソッドを呼び出そうとすると、期待どおりに NullPointerException、が発生します。

しかし、 「null」が印刷されるのはなぜですか? 実際にはnullとは何ですか?

JVM仕様には、 null がすべての参照のデフォルト値であると記載されているため、Stringに特に関連付けられていません。 実際、この仕様では、nullの具体的な値のエンコードは義務付けられていません。

では、文字列を印刷するための「null」はどこから来るのでしょうか。

PrintStream# println の実装を見ると、 String#valueOfが呼び出されていることがわかります。

public void println(Object x) {
    String s = String.valueOf(x);
    synchronized (this) {
        print(s);
        newLine();
    }
}

そして、 String#valueOfを見ると、答えが得られます:

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

そして、明らかに、それが「null」の理由です。

8. 結論

この記事では、Stringの初期化について説明しました。 宣言と初期化の違いを説明しました。 また、newの使用とリテラル構文の使用についても触れました。

最後に、null値をStringに割り当てることの意味、 null 値がメモリ内でどのように表されるか、およびどのように見えるかを確認しました。印刷するとき。

この記事で使用されているすべてのコードサンプルは、Githubから入手できます。