2

最近、Java コードのリファクタリングを開始しました。後で、オブジェクトの一部が「適切な参照」を失ったことに気付きました。つまり、オブジェクトが「参照渡し」ではなく値渡し」になっていることに気付きました。Javaは常に値渡しであり、参照渡しはメモリアドレスの受け渡しによってのみエミュレートされることを理解していることに注意してください(これが、2つのフレーズを引用する理由です)。

私の質問は次のとおりです。違いはありますか

Object o = new Object();

Object o = makeMeAnObjectPlease();

どこ

public Object makeMeAnObjectPlease()
{
    Object c = new Object();
    return c;
}

そして違いによって、内部で作成されたものと同じメモリアドレスを参照したo後になるということですか?そして、それ以上の違いはありますか?Object o = makeMeAnObjectPlease()makeMeAnObjectPlease()

4

4 に答える 4

3

はい、同じオブジェクトを参照します。いいえ、他に違いはありません。例をさらに進めるには:

Date d = makeMeAnObjectPlease();
System.out.println(d);
Date d2 = d;
changeMyObjectPlease(d2);
System.out.println(d);
System.out.println(d2);

Date makeMeAnObjectPlease() {
    return new Date();
}

void changeMyObjectPlease(Date date) {
    date.setTime(1234);
}

そのコードには正確に 1 つの Date オブジェクトがありますが、異なる時期に異なる名前で知られています。changeMyObjectPlease()最終的に、すべての名前は同じオブジェクトを指しているため、最終的に、オブジェクトを 2 つの異なる名前で出力すると、メソッドによって変更されたメモリ内の同じオブジェクトを実際に示していることがわかります。上記の実行例は次のとおりです。

Thu Jan 31 19:29:29 CST 2013
Wed Dec 31 18:00:01 CST 1969
Wed Dec 31 18:00:01 CST 1969
于 2013-02-01T01:24:30.597 に答える
2

2つのアプローチの間に機能的な違いはありません。

最初の例では、anew Objectが作成され、オブジェクトの参照場所がObject参照変数に格納されますo

2番目の例では、同じプロセスが。に対して発生しcます。次に、c(作成されたオブジェクトへのメモリ参照)の値がにコピーされoます。この時点でcとの両方がスコープ内にある場合、 (メソッドの呼び出しまたはフィールドの変更によって)行われた変更はすべて反映され、その逆も同様です。ooc

Javaで参照がどのように機能するかについての質問に答えるには、次のことを考慮してください。

Object o,c;
o = c = new Object();

この例では、oとの両方cが同じ値(への参照Object)を持ち、同じオブジェクトを指しています。メソッドに渡しoて、それが指すオブジェクトを変更し、Objectfromにアクセスして変更を確認できcます。ただし、渡した参照に新しいオブジェクトを割り当てると(次のように)

public class Test{

    public static void main(String[] args){
        Object o,c;
        o = c = new Object();
        assignIntoTheReferencePlease(c);
        System.out.println(o == c);
    }

    public static void assignIntoTheReferencePlease(Object c){
        c = new Object();
    }
}

何も起こりません(そしてプログラムは印刷しますtrue)。

なんで?

これは、あなたが言ったことは真実であるためです-すべてのメソッド呼び出しと戻り値は値によって渡されます。これは、の参照値がcメソッド変数にコピーされることを意味しますc。その変数に対して行われた割り当ては、真のポインターではないため、外部スコープ内の他の変数には影響しません。

私はあなたの質問に答えたと思います。

于 2013-02-01T01:41:42.457 に答える
1

他の人が言ったように、あなたがそれを示すように、違いはまったくありません。

たとえば、定義makeMeAnObjectPleaseを知らなかった/制御しなかった場合、 のサブクラスを返すことができObject、コードは引き続き保持されますが、最初のオプションは常に を返しObjectます。2 番目のスタイルが一般的に使用されるのは、この抽象化のためFactory Patternです。

于 2013-02-01T01:26:33.593 に答える
1

Object o = makeMeAnObjectPlease() の後で、makeMeAnObjectPlease() 内で作成されたものと同じメモリ アドレスを参照しますか?

Java のメモリ アドレスについては触れません。同じオブジェクトを参照します。どうしてできなかったのですか?

そして、それ以上の違いはありますか?

余分なメソッド呼び出しのみ、およびその中にあるものは何でも。

于 2013-02-01T01:27:36.243 に答える