32963


まず、以下のようなプログラムがあります。

[code]

    public class Test {
    
       public Test(int value){
            num = value;
       }
    
       private int num;
    
       private String str = "value:" + num;
    
       public void aaa(){
          System.out.println(str);
       }
    }
    
[/code]

Testクラスインスタンス生成時に、引数として「5」を渡した場合、  
aaa()の出力結果で、「value:5」と出てほしいのですが、現在は「value:0」となってしまいます。

解決方法の分かる方がいましたら、ご教授をお願い致します。


CC BY-SA 3.0
2017-02-27T01:00:30.363
32962
2017-02-27T04:00:13.760
2017-02-27T04:00:13.760
49
7626
question
java
Java メンバ変数を参照しているメンバ変数の初期化について


[初期化子やコンストラクタの実行タイミング](http://minor.hatenablog.com/entry/20101122/1290437595)
は、まずクラスロード時点でstatic変数の初期化が実行され、その後にコンストラクタによるインスタンス生成が行われます。

`str`変数が1度作成されると、その後に`num`の値を変更しても`str`の値は変わりません。  
例えば以下の対応方法が考えられます。

[code]

    //方法1. numと一緒にstrも初期化
    public Test(int value) {
        num = value;
        str = "value:" + num;
    }
    //方法2. numを設定するメソッドを作ってnumと一緒にstrも初期化
    public Test(int value) {
        setNum(value);
    }
    private setNum(int value) {
        num = value;
        str = "value:" + num;
    }
    //方法3. numもstatic変数にして、動的にstrを生成するためのgetStrメソッドを作る
    private static int num;
    private static String getStr() {
        return "value:" + num; //この方法ならインスタンス初期化時に更新されたnumが反映される
    }
    
[/code]


CC BY-SA 3.0
2017-02-27T01:26:50.647
32963
2017-02-27T01:26:50.647
9820
32962
answer


payanecoさんの回答で解決方法については提示されているので、`value:0`が出力される理由について記載します。  
[payanecoさんのリンク先](http://minor.hatenablog.com/entry/20101122/1290437595)に詳細な説明がありますが、このプログラムでの初期化順序は以下の通りです。

  1. インスタンス生成前  
・numが0で初期化される  
・strが"value:0"で初期化される

  2. インスタンス生成時(コンストラクタ)  
・numに引数valueの値(5)が代入される

なのでstatic変数、instance変数に関係なく初期化時にstrに設定された値("value:0")を変更していない為、`value:0`が出力されてしまいます。


CC BY-SA 3.0
2017-02-27T01:56:12.233
32964
2017-02-27T01:56:12.233
20272
32962
answer