日期:2014-05-20  浏览次数:20861 次

两个类互相交叉的问题 谢谢
1. class TestA {
2. TestB b;
3. TestA() {
4. b = new TestB(this);
5. }
6. }
7. class TestB {
8. TestA a;
9. TestB(TestA a) {
10. this.a = a;
11. }
12. }
13. class TestAll {
14. public static void main (String args[]) {
15. new TestAll().makeThings();
16. // ...code continues on
17. }
18. void makeThings() {
19. TestA test = new TestA();
20. }
21. }
Which two statements are true after line 15, before main completes? (Choose two)
A. Line 15 causes a stack overflow.
B. An exception is thrown at runtime.
C. The object referenced by a is eligible for garbage collection.
D. The object referenced by b is eligible for garbage collection.
E. The object referenced by a is not eligible for garbage collection.
F. The object referenced by b is not eligible for garbage collection.
答案是cd.

整个程序过程不是太懂,哪位大哥帮忙解释一下 谢谢了!

------解决方案--------------------
1. class TestA { //类TestA
2. TestB b; //类TestA的成员变量b,是一个TestB类型的
3. TestA() { //类TestA的无参构造函数
4. b = new TestB(this); //实例化类TestA时将成员变量b赋值,调用了TestB的构造方法,传入本实例化TestA对象本身.
5. } 
6. } 
7. class TestB { //类TestB
8. TestA a; //类TestB的成员变量a ,是一个TestA类型的
9. TestB(TestA a) { //类TestB的构造函数。参数为TestA类型.
10. this.a = a; //将传入的参数赋值给成员变量a.
11. } 
12. } 
13. class TestAll { //TestAll类
14. public static void main (String args[]) { //main函数
15. new TestAll().makeThings(); //创建一个TestAll匿名对象出来并调用makeThings()方法
16. // ...code continues on 
17. } 
18. void makeThings() { //makeThings()方法
19. TestA test = new TestA(); //创建一个新的TestA类型变量test.
20. } 
21. } 
//题目意思:在15行之后和main方法结束前,哪两种说法是正确的?
Which two statements are true after line 15, before main completes? (Choose two) 
A. Line 15 causes a stack overflow. //A:15行发生一个堆栈溢出
B. An exception is thrown at runtime. //B:会产生一个运行期间异常
C. The object referenced by a is eligible for garbage collection. //C: a引用对象成为了垃圾.
D. The object referenced by b is eligible for garbage collection. //D: b引用对象成为了垃圾.
E. The object referenced by a is not eligible for garbage collection. //E: a引用对象没有成为垃圾.
F. The object referenced by b is not eligible for garbage collection. //F: b引用对象没有成为垃圾.


分析:
答案A明显是错误的,虽然类TestA的构造函数里new了一个类TestB,但在类TestB的构造函数中,只是将传入的TestA类对象赋值给自己的成员变量b.所有并没有产生循环调用,也就不会产生内存溢出.
答案B也是错的,理由同答案A差不多.
答案C和D是正确的,第15行在new出一个TestAll匿名对象后,调用了makeThings()方法.先不看这个方法.我们知道匿名对象只是拿来用用,就象厕纸一样,用了就丢了,所以第16行时候,这个没有名字的TestAll对象将会成为垃圾(用题目的话来说就是符合垃圾收集的标准).然后我们再来看他调用的这个makeThings()方法,这个方法虽然new了一个有名字的对象,但是很遗憾,他在超出方法代码后,也成为了垃圾.那么他所产生的a对象和b对象都成为了垃圾.
答案E和F是也是错的。


------解决方案--------------------
1. TestB的对象和TestA的对象构成了循环引用,又不是循环调用,只不过是建立了一个TestA的对象,一个TestB的对象,各自的成员变量引用了对方。不会无限执行下去。
2. makeThings() 方法执行完了test自然会出作用域。