0

重複の可能性:
Java 参照渡しの問題

以下の私のコードでは、methodAが呼び出され、 への呼び出しをデリゲートします。methodBその際にmethodB、入力パラメータに文字列リテラル「bbb」を割り当てますが、に戻ってmethodA、文字列リテラルはそこにありませんでした。JLS のどのセクションでこれが定義されていますか?行動?

package sg.java.test2;

public class TestApple {
    public static void main(String args[]){
        methodA();
    }

    public static void methodA(){
        String a = null; 

        methodB(a);

        System.out.println(a);
    }

    public static void methodB(String a){
        a = new String("bbb");
    }
}
4

2 に答える 2

4

これは、値渡しと参照渡しの問題です。Java は値渡しのみです。電話すると

methodB(a)

参照aがコピーされます。のコンテキストではmethodBaは と同じ値を持つ別の変数ですmethodA。そのため、 で変更してもmethodBainmethodAは元の文字列を指したままです。

ここで問題になるもう 1 つの問題は、文字列は不変であるため、一度設定すると文字列の値を変更できないことです。ドキュメントから。

文字列は定数です。作成後に値を変更することはできません。

あなたができることは

a = methodB();

"bbb"に戻りmethodBます。aあなたはそれを操作していないので、パスする理由はありません。aを呼び出すコンテキストで変更しようとするためだけにそれを行っていたと思いますがmethodB、これはできません。

最後に、JLS の関連部分は8.4.1です。

メソッドまたはコンストラクターが呼び出されると (§15.12)、実引数式の値は、メソッドまたはコンストラクターの本体の実行前に、新しく作成されたパラメーター変数、宣言された Type のそれぞれを初期化します。DeclaratorId に表示される Identifier は、メソッドまたはコンストラクターの本体で単純な名前として使用して、仮パラメーターを参照できます。

于 2011-09-21T16:01:39.710 に答える
2

Java は参照渡しではなく、値渡しです。

メソッド シグネチャはこれを省略したものです。

methodB() {
    String a = arguments[0];

つまり、差分参照です。'a' に代入すると、methodB() への呼び出しを含むコード ブロックで宣言した 'a' ではなく、メソッド シグネチャの一部として作成された参照 'a' に代入されます。

ただし、オブジェクトの場合は値を変更できます。

class MyObj {
    String prop;
    public MyObj(String s) { prop = s; }
    public MyObj() { }
}

public void methodB(MyObj o) {
    o.prop = "foo";
}

public void methodA() {
    MyObj a = new MyObj();
    System.out.println(a.prop); // null
    methodB(a);
    System.out.println(a.prop); // foo
}
于 2011-09-21T16:01:28.880 に答える