1

このプログラムがどのように実行されるか説明してもらえますか?

これは、出力がまったく得られないように見えるコードです。

    class Box {
        int size;
        Box (int s) {
           size = s;
        }
    }
    public class Laser {
        public static void main(String[] args) {
            Box b1 = new Box(5);
            Box[] ba = go(b1, new Box(6));
            ba[0] = b1;
            for(Box b : ba)
                System.out.println(b.size + " ");
        }

        static Box[] go (Box b1, Box b2) {
            b1.size = 4;
            Box[] ma = {b2, b1};
            return ma;
        }
    }

これを実行したときの実際の出力は 4, 4 です。しかし、私の理解によれば、これは 5, 4 である必要があります。

4

7 に答える 7

3

コメントを追加しました。

The important TWIST that you missed here is;

Box[] ma = {b2, b1};そうではありません{b1,b2}。メモリの場所は、戻るときに交換されます。

       public static void main(String[] args) {
            Box b1 = new Box(5);                 // b1 == location A
            Box[] ba = go(b1, new Box(6));       // ba == location B which stores Location A, D

           // PLEASE NOTE HERE
           // After the function go() is executed;
           // ba[] will have {D, A}
           // So ba[0] will have object b1 which is at location A. 

            ba[0] = b1;                          // location B will now store A and A
            for(Box b : ba)
                System.out.println(b.size + " ");  //  Output: 4 and 4
        } 

        static Box[] go (Box b1, Box b2) {        // go(location A, location D )
            b1.size = 4;                          // A's object.size = 4
            Box[] ma = {b2, b1};                  // position is interchanged here (D and A)
            return ma;                            // return the location of ma
        }

お役に立てれば。

ご不明な点がございましたら、お気軽にお問い合わせください。Javaではすべてが値渡しです。メモリアドレスは値で渡されます。

于 2013-08-13T15:38:13.037 に答える
0

オブジェクトをパラメーターとして渡す場合、実際にはオブジェクトへの参照のコピーを渡しています。つまり、メソッド内でパラメーター オブジェクトを変更すると、そのメソッドが戻ったときにオブジェクトはそれらの変更をb1保持しsize = 4ますgo

于 2013-08-13T15:34:24.370 に答える
0

Java は常に、メソッド呼び出しでオブジェクトへの参照を渡します。を呼び出しているときgo、最初の引数 ( b1) は、 にあるものと同じb1 Boxものへの参照ですmain。次に、そのオブジェクトを変更します。そのオブジェクトsizeは現在4です。

于 2013-08-13T15:35:39.023 に答える
0

に渡される値は、オブジェクトへのgo参照です。C から来た場合、パラメーターは次のようなポインター型を持つと考えることができます。

Box** go (Box *b1, Box *b2) {
     b1->size = 4;
     /* allocate an array of Box*, set it up, return it */
}

(C の構文が間違っていたらごめんなさい。) ポインター (参照) 自体は値によって渡されます。

b1 = &some_other_box;

呼び出し側の変数には影響せず、Java でも同じように機能します。varこれは、PHP や Pascalのパラメーターとは少し異なります。

于 2013-08-13T15:38:21.860 に答える
0

元の投稿の関数 'go' が C にある場合 (および b1 と b2 が C ポインターである場合)、次の 2 つのことを行うことができます (呼び出し元に表示されます)。

  1. b1 と b2 が指すデータ構造の変数の値を変更します。
  2. 元の b1 と b2 が異なるデータ構造を指すようにします。

Java では、go は元の b1 と b2 にアクセスできないため、1 は実行できますが 2 は実行できません。(これは b1 と b2 のコピーにアクセスできます。サブルーチンの開始時に、コピー b1 は元の b1 と同じオブジェクトを指しているなどです。)

Java が呼び出しによる受け渡しであると言うと、何かが失われます。つまり、b1 と b2 によって参照されるヒープ内のオブジェクトのプロパティを変更する関数の機能が失われます。[これが b1.size = 4; というステートメントで発生し、元の投稿者の混乱を引き起こしました。]

「go」の b1 は、「main」の b1 と同じ場所ではありません。ただし、関数が開始されると、'go' の b1 は 'main' の b1 と同じオブジェクトを参照し、'go' の b1 を使用してオブジェクトに加えられた変更は、'main' の b1 が参照として使用されるときに表示されます。

ただし、「go」の b1 が別のボックスに設定されている場合、「main」の b1 にはこれが表示されません。以前のボックスが引き続き表示されます。

于 2013-12-28T11:35:31.940 に答える
-1

Java では、オブジェクトは参照によって渡され、プリミティブは値によって渡されます。

public class Laser {
    public static void main(String[] args) {
        //Create a Box of size 5.
        Box b1 = new Box(5);
        //Create an array of Box objects, which are the results of the go method
        Box[] ba = go(b1, new Box(6));
        // ba now looks like {new Box(6), b1 /*b1 is size 4 now*/}
        // assign reference to b1 at index 0 in ba.
        ba[0] = b1;
        // array now looks like {b1, b1}
        for(Box b : ba)
            System.out.println(b.size + " ");
    }

    static Box[] go (Box b1, Box b2) {
        //set the size of the first box to 4
        b1.size = 4;
        //create an array of boxes, with b2 in index 0 and b1 in index 1
        Box[] ma = {b2, b1};
        return ma;
    }
}
于 2013-08-13T15:34:07.440 に答える