Java賦値と伝参時によく無視される問題
- package com.lj.test;
-
- class Number{
- int i;
- }
- public class Test {
-
- public static void main(String[] args) {
- Number n1 = new Number();
- Number n2 = new Number();
- n1.i = 9;
- n2.i = 47;
- System.out.println("1:n1.i="+n1.i+",n2.i="+n2.i);
- n1 = n2;
- System.out.println("2:n1.i="+n1.i+",n2.i="+n2.i);
- n1.i = 27;
- System.out.println("3:n1.i="+n1.i+",n2.i="+n2.i);
- }
- }
結果はどうなると思いますか?
1:n1.i=9,n2.i=47 2:n1.i=47,n2.i=47 3:n1.i=27,n2.i=27
まず,2つのオブジェクトn 1とn 2をインスタンス化し,そのi値に対応する値を与えた.次にn 2をn 1に割り当て、n 1を修正します.多くの他のプログラミング言語では、n 1とn 2は最初から最後まで2つの独立したオブジェクトであることが考えられます.しかしJavaではn 1の修正がn 2に影響します!このときn 1とn 2は同じメモリを使用し,元のn 1オブジェクトが消費したメモリはゴミ回収器によって消去されることが分かる.個人的には、付与操作時に結果が出力されると油断することが多いと思います:3:n 1.i=27、n 2.i=47.
次にThinking in Java 3 rd Editionを参考にして、メソッド呼び出しの際にパラメータを渡す際にも注意してください.
- package com.lj.test;
-
- class Number{
- int i;
- }
- public class Test {
- public static void f(Number n){
- n.i = 88;
- }
- public static void main(String[] args) {
- Number n3 = new Number();
- n3.i = 33;
- System.out.println("n3.i:"+n3.i);
- f(n3);
- System.out.println("n3.i:"+n3.i);
- }
- }
出力結果:
n3.i:33 n3.i:88
2つの例でまとめてみましょう.ベースタイプの割り当ては値のコピー操作であり、オブジェクトの割り当てはメモリアドレス参照操作(オブジェクトをパラメータとするメモリアドレスの参照操作も含む)であり、複数のオブジェクトがこのメモリアドレスを参照する場合、いずれかのオブジェクトが同じメモリを参照する他のオブジェクトを変更すると、影響を受けます.