来自Java in a Nutshell
内部类只是语法糖,因此锁定内部类 对封闭类没有影响(反之亦然)。
内在的语法糖是什么?换句话说,内部类可以根据其他更基本的结构等效地重写吗?
感谢。
答案 0 :(得分:6)
内部类Inner
,如下所示:
package some.pkg;
class Outer {
class Inner {}
}
在编译时成为这样的类:
package some.pkg;
class Outer$Inner {
private final Outer this$0;
Outer$Inner(Outer this$0) {
this.this$0 = this$0;
}
}
您可以手动声明此课程。
嗯,它几乎就像那样。有一些细节可以提供Inner
成员对Outer
个实例的访问权限;但这是广泛的。
哦,这很有趣。 生成的代码中存在差异。
如果编译“含糖”代码,则Outer$Inner
的反编译字节码为:
some.pkg.Outer$Inner(some.pkg.Outer);
Code:
0: aload_0
1: aload_1
2: putfield #1 // Field this$0:Lsome/pkg/Outer;
5: aload_0
6: invokespecial #2 // Method java/lang/Object."<init>":()V
9: return
如果您反编译“desugared”版本(使用$
s),则为:
some.pkg.Outer$Inner(some.pkg.Outer);
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: aload_0
5: aload_1
6: putfield #2 // Field this$0:Lsome/pkg/Outer;
9: return
换句话说,{/ 1}}字段在在第一种情况下调用父构造函数之前分配,而在第二种情况下调用。
我能看到的唯一区别是它允许你将this$0
作为参数传递给父构造函数(例如Outer.this
;或者允许父构造函数使用该值调用方法是super(Outer.this)
(这是严重的,因为在调用该方法时可能尚未初始化其他字段;但仍然允许这样做。)
所以,我把它拿回来:你不能完全手工实现同一个类;但两者之间的区别仅在一个非常罕见的用例中很重要。
答案 1 :(得分:2)
正如评论中所提到的,内部类只是用于声明一个单独的顶级类的语法糖。如果你想要使用两个类和差异,它基本上是相同的。创建由ONLY封闭类使用的类(逻辑上分组在一个地方使用的类)。在这种情况下,您可能希望从Java文档中使用它们(并添加此语法糖)的原因是:
这是一种逻辑分组仅在一个地方使用的类的方法。
它增加了封装。
它可以带来更易读和可维护的代码。