Java 内部类是轻量级的吗?

Java 内部类是轻量级的吗?,java,closures,inner-classes,permgen,Java,Closures,Inner Classes,Permgen,内部类是否比普通类更轻量级,或者最终java会像普通类一样编译内部类 我知道java中的类本身并不是非常轻量级的,它们占用了permgen内存的一部分,所以我想知道是否最好使用类似闭包的函数作为内部类,或者标准类也可以吗?内部类和匿名内部类都编译成.class文件。例如: class Outer { class Inner { } Object function() { return new Object() { };

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


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

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

class Outer {
     class Inner {

     }

     Object function() {
          return new Object() {

          };
     }
}

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

它们不是轻量级的,但它们有局限性。好了,一个匿名内部类不能创建多个实例,因此如果需要,必须使用非匿名类

编辑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);
JPanel面板=新的JPanel(新的网格布局(5,5));
JButton[]按钮=新JButton[25];
对于(int i=0;i<25;i++){
最终整数btnNumber=i;
按钮[i]=新的JButton(String.valueOf(btnNumber));
按钮[i].addActionListener(新建ActionListener()){
已执行的公共无效操作(操作事件e){
系统输出打印项次(“从按钮”+BTN编号);
}
});
面板。添加(按钮[i]);
}
showMessageDialog(空,面板);

但即便如此,这里创建的每个匿名类都是不同的。若同一类型的侦听器被多个JButtens使用,并且具有状态,并且其行为取决于该状态,则这可能具有重要意义。同意吗?不同意?提前感谢您的任何意见

内部类仍然是类,它们仍然必须由类加载器加载。如果说有什么不同的话,那恰恰相反。非静态内部类可以防止父类被垃圾收集,因为它引用了拥有它的类。

JVM只有基本数据类型(
int
float
等)和类。它们之间什么都没有。例如,通过将类放入
for
循环并多次实例化,可以拥有匿名内部类的多个实例。我认为Java要求这些类都具有相同的类型,但我不记得这是否正确。你想得太多了。匿名内部类仍然是一个类。您可以拥有任意多的实例。您还可以指定任意数量的匿名内部类。编译器在编译时处理所有这些。它找到的第一个匿名规范的名字是Foo$1,第二个是Foo$2,依此类推。类似于newrunnable(){…}的代码将变成Foo.new 1()。感谢您的评论和有用的信息!请为我澄清。。。如果我有一个匿名的内部ActionListener,我怎么可能有这个类的两个不同实例(没有反射),因为它是在对象创建时创建的。我知道我可以有许多匿名ActionListeners的实例,但我想知道如何可能有一个已声明的不同匿名类的多个实例。编辑:由于我没有收到澄清,我在此处为此问题创建了一个新的线程/问题:。如果可以的话,请告诉我。谢谢+1.如果有什么内部类是“重”的,因为它们包含编译器创建的合成方法和字段,以促进它们关于其包含类的特殊可见性规则。+1。除了父引用之外,还有一些合成方法允许从相关类调用“private”方法。