内部类是否比普通类更轻量级,或者最终java是否像普通类一样编译内部类?
我知道java中的类本身并不都非常轻量级,并且它们占用了permgen内存的一部分,所以我想知道最好是使用类似闭包的函数作为内部类,还是标准类也是如此做得好吗?
答案 0 :(得分:19)
内部类和匿名内部类都编译为.class
个文件。例如:
class Outer {
class Inner {
}
Object function() {
return new Object() {
};
}
}
将生成三个.class
个文件,Outer.class
,Outer$Inner.class
和Outer$1.class
。它们并不比其他类更“轻量级”,并且(据我所知)从性能角度来看,使用one over other是没有优势的。当然,内部类,特别是匿名内部类在常规类更难编码的上下文中非常有用,但这是一个单独的问题。
答案 1 :(得分:7)
内部类仍然是类,它们仍然必须由ClassLoader加载。如果有的话,情况正好相反。非静态内部类可以使父类不被垃圾收集,因为它具有对拥有它的类的引用。
答案 2 :(得分: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使用相同类型的侦听器,它具有状态,并且其行为取决于此状态,则这可能具有重要意义。同意?不同意?提前感谢任何输入!