2010-02-19 45 views
3

爲了記錄在案,我不一個 Java初學者,但 - 而 - 中間級的傢伙誰有點忘了介紹一下關於Java的基本面。爲什麼指定的對象有資格進行垃圾回收?

class C{ 
    public static void main(String a[]){ 
     C c1=new C(); 
     C c2=m1(c1);  //line 4 
     C c3=new C(); 
     c2=c3;    // line 6 
     anothermethod(); 
    } 
    static C m1(C ob1){ 
     ob1 =new C();  // line 10 
     return ob1; 
    } 
    void anothermethod(){} 
}

從上面的代碼:

  • 爲什麼是它管線6後,C型的2個對象是符合垃圾收集(GC)?

  • 爲什麼不是在第4行和第10行,一個拷貝的c1傳遞到m1()方法。因此,最終在第6行中,將有1個對象(不是2個)將有資格獲得GC。畢竟,不是java傳遞值而不是傳遞引用?

+2

你用漂亮的代碼混淆 – Roman 2010-02-19 16:13:29

+1

這個代碼不應該編譯:'anothermethod'不是靜態的,而是被稱爲靜態上下文 – 2010-02-19 17:24:21

回答

1

什麼讓你覺得C類型的兩個對象可用於GC 6號線後?我只看到一個(c2)。你使用什麼工具,否則會告訴你?

關於你提到的有關將c1到您的m1方法的問題:你通過什麼(按價值計算)是對對象的引用 - 一個手柄,通過它可以,如果你會搶對象, - 而不是它的一個副本。事實上,將參考文件傳遞到m1的事實是完全不相關的,事實上 - 您從不使用該參考,您立即用對新對象的引用覆蓋它,然後返回該對象(這不會影響仍在引用的c1main)。

+0

請參考下面的鏈接問題13:http://www.examsguide.com/scjp/ freequestions2.html – Catfish 2010-02-19 16:53:57

+0

@Catfish:我們不是唯一認爲他們錯了的人:http://www.coderanch.com/t/452512/Programmer-Certification-SCJP/certification/help-garbage-collection – 2010-02-19 17:18:52

+0

@鮎魚:就他們而言,他們是錯的。從代碼中的第6行開始(和它們看起來大致相同),第一個創建的(由main創建的)C仍然在main中被引用爲c1;由m1創建的第二個C不再被引用(因爲引用它的變量不引用第三個)並且可能是GC'd;由main創建的第三個實例仍然由'main'中的'c2'和'c3'引用。因此,第二個對象是唯一準備用於GC的對象。至少(該代碼中提到的唯一一個)。如果你讀過我早期的故障,我會抱怨我的'c2'和'c3'混淆。 :-) – 2010-02-19 17:22:15

4

Is Java Pass By Reference通引用按值和傳遞值按參考:)之間的差異
Java is never pass by reference right right
Pass By Reference Or Pass By Value

你可能想看看喬恩Skeet的關於C#參數傳遞語義的文章,因爲它是他最喜歡的'程序員無知'pet peeve:
What's your favorite 'programmer ignorance' pet peeve

所以基本上,我看到你的代碼執行以下操作:

c1 = new C("Alice"); 
    // m1(C obj1) {  -- c1 gets passed to m1, a copy of the reference is made. 
    //     -- there are now two references to Alice (c1, obj1) 
    // obj1 = new C("Bob"); -- there is now one reference to Alice 
           // and one reference to Bob 
    // return obj1; -- returns a reference to Bob(c1 still reference Alice) 
    // }    -- when m1 returns, one of the references to Alice disappears. 
c2 = m1(c1); // c2 points to Bob 
c3 = new C("Charlie"); 
c2 = c3;  // <-- Bob is eligible for collection. 
       // There are now two references to Charlie