内部类比普通类更轻量级吗?或者说最终java编译内部类和普通类一样吗?
我知道在java中,类本身并不都是非常轻量级的,并且它们占用了permgen内存的一部分,所以我想知道是否最好使用类似闭包的函数作为内部类,还是标准类也可以胜任?
内部类比普通类更轻量级吗?或者说最终java编译内部类和普通类一样吗?
我知道在java中,类本身并不都是非常轻量级的,并且它们占用了permgen内存的一部分,所以我想知道是否最好使用类似闭包的函数作为内部类,还是标准类也可以胜任?
内部类和匿名内部类都会编译成.class
文件。例如:
class Outer {
class Inner {
}
Object function() {
return new Object() {
};
}
}
将会生成三个.class
文件,分别是Outer.class
,Outer$Inner.class
和Outer$1.class
。它们并不比其他类更加“轻量级”,就我所知并没有从性能方面使用一个而不是另一个的优势。当然,在常规类难以编码的情况下,内部类特别是匿名内部类非常有用,但这是另一个问题。
内部类仍然是类,它们仍然需要由ClassLoader加载。事实上,相反的情况更为真实。非静态内部类可以防止其父类被垃圾回收,因为它具有对拥有它的类的引用。
它们并不轻量级,但也有限制。据我所知,不能创建多个匿名内部类的实例,如果您的需求需要这样做,必须使用非匿名类。
编辑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);
但即便如此,在这里创建的每个匿名类都是不同的。如果多个JButton使用相同类型的监听器,并且它具有状态并且其行为取决于此状态,则可能具有重要意义。同意?不同意?感谢您提前提供的任何意见!
new Runnable(){...}
的代码会变成 Foo.new 1()
。 - Tim Bender
int
,float
等)和类。它们之间没有任何中间层。 - Gabe