DEV Community

TANIAOKA, Akihiro
TANIAOKA, Akihiro

Posted on • Updated on

13章5

public class Sample {
    private String value; // フィールド変数はデフォルトでnullに初期化されます。

    public void setValue(String value) {
        // ここで問題が起こります。'this'キーワードがないため、
        // フィールドの'value'ではなく、引数のローカル変数'value'が参照されています。
        // 結果として、フィールドの'value'は変更されずにnullのままです。
        value = "Hello, " + value; // 正しくは 'this.value = "Hello, " + value;' であるべきです。
    }

    public String toString() {
        // 'value' フィールドの値を返しますが、setValueメソッドではフィールドが更新されていないため、
        // このメソッドが返すのはデフォルト値の 'null' です。
        return value; // 'null' が返されることになります。
    }
}

public class Main {
    public static void main(String[] args) {
        Sample s = new Sample(); // Sampleクラスのインスタンスを生成します。
        s.setValue("Java"); // ここでは実際には何も設定されていません。フィールド'value'はnullのままです。
        System.out.println(s.toString()); // 'null' を出力します。
    }
}
Enter fullscreen mode Exit fullscreen mode

このコードを実行すると、setValueメソッド内でthisキーワードが使われていないため、Sampleクラスのvalueフィールドは変更されずにnullを保持し続けます。したがって、toStringメソッドはこのnull値を文字列として返すので、出力はnullとなります。

追記

このJavaコードにおいて、SampleクラスのsetValueメソッド内でvaluethis.valueに置き換えた場合の出力を考えます。

以下は変更されたSampleクラスのコードです。

public class Sample {
    private String value;
    public void setValue(String value) {
        this.value = "Hello, " + value;
    }
    public String toString() {
        return value;
    }
}
Enter fullscreen mode Exit fullscreen mode

この変更を加えた状態でMainクラスを実行した場合の出力は次の通りです。

public class Main {
    public static void main(String[] args) {
        Sample s = new Sample();
        s.setValue("Java");
        System.out.println(s.toString());
    }
}
Enter fullscreen mode Exit fullscreen mode

Mainクラスのmainメソッド内でsetValueメソッドが呼び出されると、this.valueは"Hello, Java"に設定されます。そして、toStringメソッドはthis.valueを返すので、最終的な出力は以下のようになります。

Hello, Java
Enter fullscreen mode Exit fullscreen mode

ですので、出力は"Hello, Java"となります。

補足

わかりやすく説明します。

まず、コード全体をもう一度確認しましょう。

public class Sample {
    private String value;

    public void setValue(String value) {
        this.value = "Hello, " + value;
    }

    public String toString() {
        return value;
    }
}

public class Main {
    public static void main(String[] args) {
        Sample s = new Sample();
        s.setValue("Java");
        System.out.println(s.toString());
    }
}
Enter fullscreen mode Exit fullscreen mode
  1. オブジェクトの作成
   Sample s = new Sample();
Enter fullscreen mode Exit fullscreen mode

ここで、Sampleクラスのインスタンスsが作成されます。この時点では、valueはまだ初期化されていません。

  1. メソッド呼び出し
   s.setValue("Java");
Enter fullscreen mode Exit fullscreen mode

ここで、ssetValueメソッドが呼び出され、引数として"Java"が渡されます。このときの流れを詳しく見てみましょう。

  • setValueメソッドの引数value"Java"が渡されます。
  1. メソッド内部の処理
   public void setValue(String value) {
       this.value = "Hello, " + value;
   }
Enter fullscreen mode Exit fullscreen mode
  • 引数として渡されたvalue"Java"です。
  • メソッド内でthis.value = "Hello, " + value;が実行されます。ここでthis.valueSampleクラスのインスタンス変数valueを指し、"Hello, " + value"Hello, Java"となります。
  • 結果として、this.valueには"Hello, Java"が代入されます。
  1. 結果の表示
   System.out.println(s.toString());
Enter fullscreen mode Exit fullscreen mode
  • 最後にtoStringメソッドが呼び出され、this.valueが返されます。この場合、this.valueには"Hello, Java"が代入されているので、"Hello, Java"が出力されます。

この流れを図にすると以下のようになります。

  1. s.setValue("Java")が呼び出される。
  2. setValueメソッドの引数value"Java"が渡される。
  3. this.value"Hello, Java"が代入される。

この一連の流れにより、valueには"Hello, Java"が設定されます。

Top comments (0)