Java:私有内部类合成构造函数

编程入门 行业动态 更新时间:2024-10-28 10:30:17
本文介绍了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:私有内部类合成构造函数

本文发布于:2023-10-31 07:03:48,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1545373.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:部类   函数   Java

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!