内部类的语法糖是什么?

时间:2017-10-15 17:50:53

标签: java

来自Java in a Nutshell

  

内部类只是语法糖,因此锁定内部类   对封闭类没有影响(反之亦然)。

内在的语法糖是什么?换句话说,内部类可以根据其他更基本的结构等效地重写吗?

感谢。

2 个答案:

答案 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文档中使用它们(并添加此语法糖)的原因是:

  • 这是一种逻辑分组仅在一个地方使用的类的方法。

  • 它增加了封装。

  • 它可以带来更易读和可维护的代码。