1. ホーム
  2. java

Integerクラスの参照渡しを正しく行うには?

2023-09-28 05:49:16

質問

私は、誰かが私のためにここで起こっていることを明確にできることを期待しています。 整数クラスで少し調べてみましたが、整数は をオーバーライドしているため + 演算子をオーバーライドしても、何が間違っているのか分かりませんでした。 私の問題は、この行にあります。

Integer i = 0;
i = i + 1;  // ← I think that this is somehow creating a new object!

以下は私の推論です。 私はjavaが値渡しであることを知っています( または参照の値で渡す ) であることを知っているので、次の例では、整数オブジェクトは毎回インクリメントされるべきだと思うのです。

public class PassByReference {

    public static Integer inc(Integer i) {
        i = i+1;    // I think that this must be **sneakally** creating a new integer...  
        System.out.println("Inc: "+i);
        return i;
    }

    public static void main(String[] args) {
        Integer integer = new Integer(0);
        for (int i =0; i<10; i++){
            inc(integer);
            System.out.println("main: "+integer);
        }
    }
}

これは私が期待する出力です。

株式会社: 1
main: 1
Inc: 2
メイン:2
株式会社:3
メイン 3
株式会社: 4
メイン 4
インク:5
メイン 5
インク:6
メイン:6
...

これが実際の出力です。

株式会社: 1
main: 0
株式会社: 1
メイン 0
株式会社: 1
メイン 0
...

なぜこのような挙動になるのでしょうか?

どのように解決するのですか?

2つの問題があります。

  1. Integerは参照ではなく値で渡される。メソッド内部で参照を変更しても、呼び出し側のメソッドで渡された参照には反映されません。
  2. Integerはimmutableです。のようなメソッドはありません。 Integer#set(i) . そうでなければ、それを利用すればいいのです。

これを動作させるためには、返り値を再代入する必要があります。 inc() メソッドの戻り値を再割り当てする必要があります。

integer = inc(integer);


値で渡すことについてもう少し学ぶために、別の例を示します。

public static void main(String... args) {
    String[] strings = new String[] { "foo", "bar" };
    changeReference(strings);
    System.out.println(Arrays.toString(strings)); // still [foo, bar]
    changeValue(strings);
    System.out.println(Arrays.toString(strings)); // [foo, foo]
}
public static void changeReference(String[] strings) {
    strings = new String[] { "foo", "foo" };
}
public static void changeValue(String[] strings) {
    strings[1] = "foo";
}