Java中的私有内部类是否存在性能开销?

时间:2011-02-10 05:07:54

标签: java performance inner-classes micro-optimization

当我有私有方法或字段的内部类时,编译器必须创建合成的包受保护的访问器方法,以允许外部类访问这些私有元素(反之亦然)。

为了避免这种情况,我通常会将所有字段和方法以及构造函数保护为包而不是私有。

但是班级本身的知名度如何呢?

是否有开销?
 private static class A {
      A(){}
 }

 static class A {
      A(){}
 }

请注意,构造函数在两种情况下都是受包保护的,或者是否使类私有更改?

3 个答案:

答案 0 :(得分:18)

您是否尝试过编译并比较字节代码?这是我的结果。为:

public class Example {
  public static void main(String[] args) {
    System.out.println("Hello world!");
  }
  private static class A {
    A(){}
  }
}

以上产生以下* .class文件:

-rw-r--r--    1 michaelsafyan  staff   238 Feb 10 00:11 Example$A.class
-rw-r--r--    1 michaelsafyan  staff   474 Feb 10 00:11 Example.class

现在,如果我移动类文件,删除private修饰符,然后重新编译,我得到:

 -rw-r--r--    1 michaelsafyan  staff   238 Feb 10 00:15 Example$A.class
 -rw-r--r--    1 michaelsafyan  staff   474 Feb 10 00:15 Example.class

如果查看VM Spec on class files,您会看到有一个用于指定访问修饰符的常量大小的位字段,因此生成的文件大小相同并不奇怪。< / p>

简而言之,您的访问修饰符不会影响生成的字节代码的大小(它也不会对性能产生任何影响)。您应该使用最有意义的访问修饰符。

我还应该补充说,如果将内部类从声明static更改为未声明static,则会略有不同,因为它意味着引用外部类的附加字段。与声明内部类static相比,这会占用更多的内存,但是为了优化这个内容你会感到疯狂(在有意义的地方使用static,在需要它的地方使用它-static,使它非静态,但不要只是为了在这里或那里保存内存指针而使你的设计卷入其中。)

答案 1 :(得分:8)

私有内部类和非私有内部类之间应该没有性能差异。

静态内部类(私有或非私有)和外部类之间应该没有性能差异。

静态内部类和非静态内部类之间存在性能差异。这种差异是由于非静态情况对其封闭类的实例具有隐藏引用。它作为额外参数传递给内部类构造函数,并存储在隐藏变量中。

答案 2 :(得分:4)

这不太可能导致任何明显的减速。

非静态内部类需要注意的一个问题是它们包含对封闭类实例的引用。

因此,这可能导致内存泄漏,因为封闭的实例无法进行垃圾回收。 如果将内部类的实例传递给调用者,则还会传递封闭类的实例。

静态内部类不是这种情况!

不建议对所有字段包进行保护以防止使用合成方法。你放弃了封装,这是一件很有价值的事情。 你有什么顾虑?附加代码的类文件大小?