当我有带有私有方法或字段的内部类时,编译器必须创建合成的包保护访问器方法,以允许外部类访问这些私有元素(反之亦然)。
为避免这种情况,我通常将所有字段、方法和构造函数设为包保护而不是私有。
但是类本身的可见性如何呢?是否有开销
private static class A {
A(){}
}
相对
static class A {
A(){}
}
请注意,在这两种情况下,构造函数都是受包保护的,还是将类设为私有会改变这一点?
当我有带有私有方法或字段的内部类时,编译器必须创建合成的包保护访问器方法,以允许外部类访问这些私有元素(反之亦然)。
为避免这种情况,我通常将所有字段、方法和构造函数设为包保护而不是私有。
但是类本身的可见性如何呢?是否有开销
private static class A {
A(){}
}
相对
static class A {
A(){}
}
请注意,在这两种情况下,构造函数都是受包保护的,还是将类设为私有会改变这一点?
您是否尝试过编译它并比较字节码?这是我的结果。为了:
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,您会发现有一个用于指定访问修饰符的固定大小的位字段,因此生成的文件大小相同也就不足为奇了。
简而言之,您的访问修饰符不会影响生成的字节码的大小(它也不应该对性能产生任何影响)。您应该使用最有意义的访问修饰符。
我还应该补充一点,如果将内部类从被声明更改static
为未声明,则存在细微差别static
,因为它意味着引用外部类的附加字段。与声明内部类相比,这将占用更多的内存static
,但是为此进行优化会很疯狂(static
在有意义的地方使用,并且在您需要它是非静态的地方,使其成为非静态的,但是不要为了在此处或那里保存内存指针而使您的设计复杂化)。
私有内部类和非私有内部类之间应该没有性能差异。
静态内部类(私有或非私有)和外部类之间应该没有性能差异。
静态内部类和非静态内部类之间的性能差异很小。这种差异是由于非静态案例具有对其封闭类实例的隐藏引用。这作为额外参数传递给内部类构造函数,并存储在隐藏变量中。
这不太可能导致任何显着的放缓。
使用非静态内部类需要注意的一个问题是它们包含对封闭类实例的引用。
因此,这可能会导致“内存泄漏”,因为封闭的实例不能被垃圾收集。如果你将内部类的实例传递给调用者,你也传递了一个封闭类的实例。
这不是静态内部类的情况!
不建议将所有字段打包以防止合成方法。您正在放弃封装,这是一种有价值的东西。你有什么顾虑?附加代码的类文件的大小?