8

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

我知道java中的类本身并不是非常轻量级的,它们占据了permgen内存的一部分,所以我想知道是否最好使用类似闭包的函数作为内部类,或者标准类也可以吗?

4

3 回答 3

19

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

class Outer {
     class Inner {

     }

     Object function() {
          return new Object() {

          };
     }
}

将生成三个.class文件,Outer.classOuter$Inner.classOuter$1.class. 它们并不比其他类更“轻量级”,而且(据我所知)从性能的角度来看,使用一个比另一个没有优势。当然,内部类,尤其是匿名内部类在常规类难以编码的情况下非常有用,但这是一个单独的问题。

于 2011-01-27T03:37:07.610 回答
7

内部类仍然是类,它们仍然必须由 ClassLoader 加载。如果有的话,情况恰恰相反。非静态内部类可以防止父类被垃圾收集,因为它具有对拥有它的类的引用。

于 2011-01-27T03:50:00.053 回答
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 使用相同类型的侦听器,这可能很重要,它具有状态,并且其行为取决于此状态。同意?不同意?提前感谢您的任何意见!

于 2011-01-27T03:43:26.973 回答