Java:私有内部类合成构造函数 [英] Java: private inner class synthesized constructors

查看:122
本文介绍了Java:私有内部类合成构造函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个外部类,其中有一个私有内部类。



在我的外部类方法中,我实例化 Inner 类,如下所示:

  Outer outer = new Outer(); 
Inner inner = outer.new Inner();

编译器将此代码转换为:

 外部外部=新外部(); 
内在=新内在(外,空);

使用反射显示内部类有以下合成的构造函数:

  private Outer $ Inner(Outer)
Outer $ Inner(Outer,Outer $ Inner)

由于 Inner 类是 private ,编译器将 private 构造函数添加到其中,因此没有人可以实例化该类。但显然外部类应该能够实例化它,因此编译器会添加其他包私有构造函数,后者又调用私有构造函数。此外,由于package-private构造函数的名称中包含 $ ,因此普通Java代码无法调用它。



<问题:为什么要合成一个私有和一个包私有构造函数?为什么不合成package-private构造函数并用它完成呢?

解决方案

如果你编写代码,

  public class Outer {
private class Inner {}
}

你会注意到只有一个构造函数 private Outer $ Inner(Outer)



这个构造函数是Section 8.8.9的JLS ,它表示如果没有定义构造函数,则必须生成默认构造函数,在这种情况下,默认构造函数必须是私有的,


在类类型中,如果类被声明为public,则默认的
构造函数被隐式赋予访问修饰符public(§6.6) );如果
该类被声明为protected,那么默认构造函数是
隐式赋予访问修饰符protected(§6.6);如果该类是
声明为private,则默认构造函数隐式赋予
访问修饰符private(§6.6);否则,默认构造函数的
是无访问修饰符暗示的默认访问。


但是,当您实例化实例时内部内部的代码,例如,

 公共类外部{
私人类内部{}
public String foo(){
返回new Inner()。toString();
}
}

编译器必须生成Outer合法的构造函数调用(您不能合法地调用私有默认构造函数,因为它是私有的)。因此编译器必须生成一个新的合成构造函数。新的构造函数必须是合成的,根据第13.1节JLS


编译器引入的任何构造在源代码中没有
对应的构造必须标记为
synthetic,除了默认构造函数和类
初始化方法。


第二个构造函数源代码中没有相应的构造,因此这个新的构造函数必须是合成的。仍然必须生成第一个私有构造函数,因为JLS需要私有默认构造函数。


I have an Outer class which has a private Inner class.

In my Outer class method, I instantiate the Inner class as follows:

Outer outer = new Outer();
Inner inner = outer.new Inner();

The compiler converts this code to:

Outer outer = new Outer();
Inner inner = new Inner(outer, null);

Using reflection shows that the Inner class has the following synthesized constructors:

private Outer$Inner(Outer)
Outer$Inner(Outer,Outer$Inner)

Since the Inner class is private, the compiler adds that private constructor to it so nobody can instantiate that class. But obviously the Outer class should be able to instantiate it, so the compiler adds that other package private constructor which in turn calls the private constructor. Also, since the package-private constructor has that $ in its name, normal Java code can't call it.

Question: why synthesize one private and one package-private constructor? Why not synthesize only the package-private constructor and be done with it?

解决方案

If you write the code like,

public class Outer {
      private class Inner {}
}

You will note that there is only one constructor private Outer$Inner(Outer)

This constructor is required by Section 8.8.9 of the JLS, which says that if no constructor is defined a default constructor must be generated, and in this case the default constructor must be private,

In a class type, if the class is declared public, then the default constructor is implicitly given the access modifier public (§6.6); if the class is declared protected, then the default constructor is implicitly given the access modifier protected (§6.6); if the class is declared private, then the default constructor is implicitly given the access modifier private (§6.6); otherwise, the default constructor has the default access implied by no access modifier.

However, when you you instantiate an instance of Inner inside Outer with code like,

public class Outer {
    private class Inner {}
        public String foo() {
            return new Inner().toString(); 
        }
}

The compiler has to generate a constructor that Outer can legally call (you can't legally call the private default constructor because it is private). So a new synthetic constructor must be generated by the compiler. The new constructor must be synthetic, according to section 13.1 of the JLS

Any constructs introduced by the compiler that do not have a corresponding construct in the source code must be marked as synthetic, except for default constructors and the class initialization method.

This second constructor has no corresponding construct in the source code, so this new constructor must be synthetic. The first private constructor must still be generated, since the JLS requires a private default constructor.

这篇关于Java:私有内部类合成构造函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆