当我有私有方法或字段的内部类时,编译器必须创建合成的包受保护的访问器方法,以允许外部类访问这些私有元素(反之亦然)。
为了避免这种情况,我通常会将所有字段和方法以及构造函数保护为包而不是私有。
但是班级本身的知名度如何呢?
是否有开销? private static class A {
A(){}
}
与
static class A {
A(){}
}
请注意,构造函数在两种情况下都是受包保护的,或者是否使类私有更改?
答案 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)
这不太可能导致任何明显的减速。
非静态内部类需要注意的一个问题是它们包含对封闭类实例的引用。
因此,这可能导致内存泄漏,因为封闭的实例无法进行垃圾回收。 如果将内部类的实例传递给调用者,则还会传递封闭类的实例。
静态内部类不是这种情况!
不建议对所有字段包进行保护以防止使用合成方法。你放弃了封装,这是一件很有价值的事情。 你有什么顾虑?附加代码的类文件大小?