2011-01-27 40 views
7

內部類比正常類更輕量級,還是最終Java像普通類一樣編譯內部類?我知道java中的類本身並不都是非常輕量級的,它們佔據了permgen內存的一部分,所以我想知道是否最好使用閉包類函數作爲內部類,或者如果標準類會也罰款?內部類是否輕量級?

+1

JVM只有原始數據類型(`int`,`float`等)和類。他們之間沒有任何關係。 – Gabe 2011-01-27 03:40:07

回答

17

內部類和匿名內部類都編譯爲.class文件。例如:

class Outer { 
    class Inner { 

    } 

    Object function() { 
      return new Object() { 

      }; 
    } 
} 

會生成三個文件.classOuter.classOuter$Inner.class,並Outer$1.class。它們並不比其他課程更「輕量級」,並且(據我所知),從性能的角度來看,使用它們並沒有什麼優勢。當然,內部類和特別是匿名內部類在常規類更難編碼的上下文中非常有用,但這是一個單獨的問題。

+7

+1。如果任何內部類都「更重要」,因爲它們包含編譯器創建的綜合方法和字段,以便於他們針對包含類的特殊可見性規則。 – Thilo 2011-01-27 03:50:50

+0

哇!謝謝(你的)信息! – Waneck 2011-01-27 04:08:53

1

它們不是輕量級的,但它們有限制。 AFAIK,你不能創建一個以上匿名內部類的實例,所以如果你的需要需要這個,你必須使用一個非匿名類。

編輯1:感謝您的所有意見和澄清。請幫助我更好地理解這一點......我明白,您可以擁有多個匿名內部類的實例,但是如果我聲明瞭一個匿名內部ActionListener對象,我如何可以擁有的多個實例,並且只有該類沒有使用反射?在此先感謝(或者我應該在我自己的問題中提出這個問題?)!

好的,因爲我沒有得到任何叮咬......讓我用代碼演示。說我在這裏創建一個匿名的ActionListener:

JButton button = new JButton("Button"); 

    button.addActionListener(new ActionListener() { 
    @Override 
    public void actionPerformed(ActionEvent arg0) { 
     System.out.println("Button says \"Foo!\""); 
    } 

    }); 

    JOptionPane.showMessageDialog(null, button); 

我創建一個匿名的ActionListener,也一舉創造這個類的一個對象。我總是被教導的,我在我的帖子頂部提到的(並且被嘲笑的)是,如果不是不可能的(沒有反思的魔力)來創建這個匿名類的另一個對象,只有一個對象可以製作,並且在只需要一個對象的情況下,這很好。但在其他情況下,這並不好。而且,當然,你可以創建多個類似的匿名ActionListener的類,在for循環中:

JPanel panel = new JPanel(new GridLayout(5, 5)); 
    JButton[] buttons = new JButton[25]; 
    for (int i = 0; i < 25; i++) { 
    final int btnNumber = i; 
    buttons[i] = new JButton(String.valueOf(btnNumber)); 
    buttons[i].addActionListener(new ActionListener() { 
     public void actionPerformed(ActionEvent e) { 
      System.out.println("From button " + btnNumber); 
     } 
    }); 
    panel.add(buttons[i]); 
    } 
    JOptionPane.showMessageDialog(null, panel); 

但即便如此,在這裏創建的每個匿名類是不同的。如果多個JButtens使用相同類型的監聽器,它具有狀態,並且其行爲取決於此狀態,則這可能具有重要意義。同意?不同意?預先感謝您的任何意見!

+3

例如,您可以將匿名內部類的多個實例放入`for`循環並多次實例化。我認爲Java要求這些類都具有相同的類型,但我不記得這是否正確。 – templatetypedef 2011-01-27 03:45:48

7

內部類仍然是類,它們仍然必須由ClassLoader加載。如果有的話,情況正好相反。非靜態的內部類可以保持父類不被垃圾回收,因爲它擁有對擁有它的類的引用。