3

SCJP 6 準備本から抜粋 -

与えられた:

class CardBoard {
    Short story = 200;
    CardBoard go(CardBoard cb) {
        cb = null;
        return cb;
    }
    public static void main(String[] args) {
        CardBoard c1 = new CardBoard();
        CardBoard c2 = new CardBoard();
        CardBoard c3 = c1.go(c2);
        c1 = null;
        // do Stuff
    }
}

// doStuff に達したとき、GC の対象となるオブジェクトの数は?

A.0

B.1

C.2

D. コンパイルが失敗する

E.知ることができない

F. 実行時に例外がスローされる

正解は C です。「1 つの CardBoard オブジェクト (c1) のみが適格ですが、関連する Short ラッパー オブジェクトも適格です。」

私の質問は、c3 がコレクションの対象にならないのはなぜですか?

私の考えは -

c1.go(c2) は、ローカル参照変数 cb (c2 のコピー) を null に設定し、c3 に割り当てられた cb を返します。メソッド内で c2 自体の参照変数を変更することはできず、その背後にあるオブジェクトのみを変更できることはわかっています。ただし、参照変数 cb のコピーが null に設定され、c3 に割り当てられているように見えます。このインスタンスで c3 が返された null に設定されないのはなぜですか?

4

2 に答える 2

7

c3 に関連するオブジェクトはありません。その値は null であるため、収集するものはありません。

于 2013-09-18T14:47:38.730 に答える
1

そのSCJPの「正しい」答えは偽物です。正解は4か「わからない」です。

コードが文字どおりに読み取られる場合 ("// do Stuff" は単なるコメント)、以前に c2 から到達できたオブジェクトは、以前に c1 から参照されたオブジェクトと同じように無効であり、GC の対象となります。オブジェクトには c1.story および c2.story オブジェクトがあり、それらも一緒に消滅します。合計 4 つのオブジェクトがコレクションの対象となります。

ただし、「// do Stuff」が不明なコードのプレースホルダーである場合、そのコードは c2 を使用する場合と使用しない場合があります。コードに到達しました。したがって、「// do Stuff」が実際に何であるかがわからない場合、資格があるのは 2 または 4 のいずれかであり、どちらかを判断する方法はありません。

于 2013-09-21T07:59:47.180 に答える