Java 中的私有内部类有性能开销吗?
当我有带有私有方法或字段的内部类时,编译器必须创建合成的受包保护的访问器方法,以允许外部类访问这些私有元素(反之亦然)。
为了避免这种情况,我通常将所有字段、方法和构造函数设置为包保护而不是私有的。
但是类本身的可见性怎么样? ?
private static class A {
A(){}
}
注意构造
static class A {
A(){}
}
函数在这两种情况下都是受包保护的,或者使类私有会改变这一点吗
When I have inner classes with private methods or fields the compiler has to create synthetic package-protected accessor methods to allow the outer class to access those private elements (and vice-versa).
To avoid that, I usually make all fields and methods and constructors package-protected instead of private.
But how about the visibility of the class itself? Is there an overhead to
private static class A {
A(){}
}
versus
static class A {
A(){}
}
Note that the constructor is package-protected in both cases, or does making the class private change that?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您是否尝试过编译它并比较字节码?这是我的结果。对于:
上面生成以下 *.class 文件:
现在,如果我移动类文件,删除
private
修饰符,然后重新编译,我得到:如果您查看 VM Spec on class files,您会看到有一个常量- 大小的位字段用于指定访问修饰符,因此生成的文件大小相同也就不足为奇了。
简而言之,您的访问修饰符不会影响生成的字节代码的大小(也不应该对性能产生任何影响)。您应该使用最有意义的访问修饰符。
我还应该补充一点,如果将内部类从声明
static
更改为不声明static
,会有细微的差别,因为这意味着引用外部类的附加字段。与声明内部类static
相比,这会占用稍多的内存,但是对此进行优化会很疯狂(在有意义的地方使用static
,在哪里使用static
)你需要它是非静态的,让它成为非静态的,但不要仅仅为了在这里或那里保存内存指针而使你的设计复杂化)。Have you tried compiling it and comparing the byte code? Here are my results. For:
The above yields the following *.class files:
Now, if I move the class files, delete the
private
modifier, and recompile, I get:If you look at the VM Spec on class files, you'll see that there is a constant-sized bit field for specifying the access modifiers, so it should not be any surprise that the generated files are the same size.
In short, your access modifiers won't affect the size of the generated byte code (it also should not have any performance impact, either). You should use the access modifier that makes the most sense.
I should also add that there is a slight difference if you change the inner class from being declared
static
to not being declaredstatic
, as it implies an additional field referencing the outer class. This will take up slightly more memory than if you declared the inner classstatic
, but you'd be insane to optimize for this (usestatic
where it makes sense, and where you need it to be non-static, make it non-static, but don't convolute your design just to save a pointer of memory here or there).私有内部类和非私有内部类之间不应该有性能差异。
静态内部类(私有或非私有)和外部类之间不应存在性能差异。
静态内部类和非静态内部类之间存在很小的性能差异。这种差异是由于非静态情况具有对其封闭类的实例的隐藏引用。它作为额外参数传递给内部类构造函数,并存储在隐藏变量中。
There should be no performance difference between a private inner class and a non-private inner class.
There should be no performance difference between a static inner class (private or not) and an outer class.
There is a small performance difference between a static inner class and a non-static inner class. This difference is due to the fact that the non-static case has an hidden reference to the instance of its enclosing class. This is passed as an extra parameter to the inner classes constructor, and stored in a hidden variable.
这不太可能导致任何显着的减速。
对于非静态内部类需要注意的一个问题是它们包含对封闭类实例的引用。
因此,这可能会导致“内存泄漏”,因为封闭的实例无法被垃圾收集。
如果将内部类的实例传递给调用者,那么您还将传递封闭类的实例。
静态内部类不是这样的!
不建议对所有字段进行包保护以防止合成方法。你正在放弃封装,这是一件很有价值的事情。
您有什么顾虑?用于附加代码的类文件的大小?
It is very unlikely this will ever cause any significant slow-down.
One issue to be aware of with non-static inner classes is that they contain a reference to the instance of the enclosing class.
As such, this can cause 'memory leaks', as the enclosing instance can't be garbage collected.
If you pass instances of inner classes out to callers, you are also passing out an instance of the enclosing class.
This is not the case with static inner classes!
Making all fields package protected to prevent synthetic methods is not advisable. You are giving up encapsulation which is a valuable thing to have.
What are your concerns? Size of your class files for the additional code?