内部类是轻量级的吗?

时间:2011-01-27 03:33:34

标签: java closures inner-classes permgen

内部类是否比普通类更轻量级,或者最终java是否像普通类一样编译内部类?

我知道java中的类本身并不都非常轻量级,并且它们占用了permgen内存的一部分,所以我想知道最好是使用类似闭包的函数作为内部类,还是标准类也是如此做得好吗?

3 个答案:

答案 0 :(得分:19)

内部类和匿名内部类都编译为.class个文件。例如:

class Outer {
     class Inner {

     }

     Object function() {
          return new Object() {

          };
     }
}

将生成三个.class个文件,Outer.classOuter$Inner.classOuter$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使用相同类型的侦听器,它具有状态,并且其行为取决于此状态,则这可能具有重要意义。同意?不同意?提前感谢任何输入!