周りに詳しい人がいないので質問します。ぜひお願いします。
ちなみに参考書の答案ではCの2つでした。
自分にはc1.go(c2)メソッドによってc2およびc3はnullが与えられていると思うのですが。
そうなると対象とされるオブジェクトは4つで、、、
どうもすっきりしないです。よろしくお願いします。
問題
「//その他の処理を実行する」に到達したとき、いくつのオブジェクトがガ-ベジコレクションの対象になりますか?
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;
//その他の処理を実行する
}
}
A. 0
B. 1
C. 2
D.コンパイルに失敗する
E.それを知る方法はない
F.ランタイム例外が投げられる
c1, c2, c3のうち、ガベージコレクトの対象になるのがc1のみというのは
t-wataさんのおっしゃるとおりです。go()メソッドがガベージコレクトと
関係ないというのも、c3への代入でオブジェクトが構築されてない、という点も
正しいです。
ただこの問題のポイントは、
「いくつのCardBoardオブジェクトがガベージコレクトの対象になるか?」
ではなく、
「いくつのオブジェクトがガベージコレクトの対象になるか?」
という点みたいですね。すなわち、c1にnullが代入された時点で、
(正しくはc1に代入されていたオブジェクトがどこからも参照されなくなった時点で)
c1からのみ参照されているc1.storyもガベージコレクトの対象に
なってしまっています。(CardBoard.storyはプリミティブ型の
short型ではなくラッパ型のShort型なので、オブジェクトとして扱われます。)
クラス宣言部で
Short story = 200;
と代入されていますが、これは CardBoard のコンストラクタで
Short story = new Short(200);
と書かれているのと等価になります。すなわちShort型のオブジェクトが
構築されている。
よってc1とc1.storyがガベージコレクトの対象となり、
cの2個が正解となります。なかなか意地悪な問題ですね。
ガ-ベジコレクションのタイミングは、わかりません。
ありがとうございます。
タイミングはたしかに誰にもわからないはずです。
しかしガーベジコレクションの対象となるオブジェクトはわかるはずなのです。
答えはBの1つだと思うけど。
ガベージコレクションの対象になるのは、
CardBoard c1 = new CardBoard();
で作成されたCardBoardオブジェクトだけです。これがこの後nullを代入されているので、//その他の処理 の時点で到達不能になっています。
ほかに作成されたオブジェクトは、
CardBoard c2 = new CardBoard();
だけで、これは、参照は握ったままです。
(c1.go(c2) メソッドには、c2の参照のコピーがわたるだけなので、呼ばれた先で引数にnullを代入されても、呼び出し元のc2の参照はnullにはならず元のまま)
また、
CardBoard go(CardBoard cb){
cb = null;
return cb;
}
は、
CardBoard go(CardBoard cb){
return null;
}
と同値です。処理的にも、ガベージコレクション的にも。
なので、
CardBoard c3 = c1.go(c2);
は
CardBoard c3 = null;
と一緒で、オブジェクトは作られないし、既存のオブジェクトの参照先を変更したりしていないので、GC対象が増えたり減ったりはしないです。
ありがとうございまいた。すっきりです。
cbはc2のコピーなのですね。
このコピーというものを間違って理解していたようです。
cbが変わればc2も変わるものだと勘違いしていました。
助かりました。
ちなみにc1.storyもオブジェクトの1つなので
これも対象となる ということのようです。
c1, c2, c3のうち、ガベージコレクトの対象になるのがc1のみというのは
t-wataさんのおっしゃるとおりです。go()メソッドがガベージコレクトと
関係ないというのも、c3への代入でオブジェクトが構築されてない、という点も
正しいです。
ただこの問題のポイントは、
「いくつのCardBoardオブジェクトがガベージコレクトの対象になるか?」
ではなく、
「いくつのオブジェクトがガベージコレクトの対象になるか?」
という点みたいですね。すなわち、c1にnullが代入された時点で、
(正しくはc1に代入されていたオブジェクトがどこからも参照されなくなった時点で)
c1からのみ参照されているc1.storyもガベージコレクトの対象に
なってしまっています。(CardBoard.storyはプリミティブ型の
short型ではなくラッパ型のShort型なので、オブジェクトとして扱われます。)
クラス宣言部で
Short story = 200;
と代入されていますが、これは CardBoard のコンストラクタで
Short story = new Short(200);
と書かれているのと等価になります。すなわちShort型のオブジェクトが
構築されている。
よってc1とc1.storyがガベージコレクトの対象となり、
cの2個が正解となります。なかなか意地悪な問題ですね。
ありがとうございます。
完璧でした!
たしかに意地悪ですよね。
c1.storyが対象なことまでは把握してましたが
このc1.go(c2)メソッドが自分にとって曲者でした。
とても参考になりました!
ありがとうございます。
完璧でした!
たしかに意地悪ですよね。
c1.storyが対象なことまでは把握してましたが
このc1.go(c2)メソッドが自分にとって曲者でした。
とても参考になりました!