gpt4 book ai didi

java - 为什么编译包含静态嵌套类的类会创建一个名为 "EnclosingClass$1"的新 .class 文件?

转载 作者:行者123 更新时间:2023-12-02 19:07:55 28 4
gpt4 key购买 nike

在下面的代码中:

 class EnclosingClass
{
public static class BiNode extends Sub.IBiLink { }
private static class Sub
{
private static class IBiLink
{
}
}
}

与其他 .class 文件一起编译时,我还看到一个名为“EnleadingClass$1.class”的文件。为什么会自动创建该文件?这是怎么回事?

最佳答案

首先看一下 JVM 规范中的类访问和属性修饰符表。

enter image description here

请注意 ACC_SYNTHETIC 标志,该标志的解释表明它不存在于源代码中(简单地说,它将在编译器生成类时添加)。

<小时/>

让我们看一下 EnlookingClass$1.class 的字节码(请注意,我将只粘贴重要的部分)。

javap -v EnclosingClass$1.class

产生以下结果

Classfile /C:/Users/jfrancoiss/Desktop/Nouveau dossier/EnclosingClass$1.class
Last modified 2015-03-31; size 190 bytes
MD5 checksum 5875440f1e7f5ea9a519d02fbec6dc8f
Compiled from "EnclosingClass.java"
class EnclosingClass$1
minor version: 0
major version: 52
flags: ACC_SUPER, ACC_SYNTHETIC

请注意,该类的访问标志包含 ACC_SYNTHETIC

The ACC_SYNTHETIC flag indicates that this class or interface was generated by a compiler and does not appear in source code.

确保生成的类是合成的另一个选项是编译为

javac -XD-printflat EnclosingClass.java

这会产生

/*synthetic*/ class EnclosingClass$1 {
}
<小时/>

很好,但是为什么要生成一个合成类?

Java反射教程可以帮助我们理解这一点。看看 SyntheticConstructor 里的评论类

public class SyntheticConstructor {
private SyntheticConstructor() {}
class Inner {
// Compiler will generate a synthetic constructor since
// SyntheticConstructor() is private.
Inner() { new SyntheticConstructor(); }
}
}

因此,根据评论,创建了合成类 EnwritingClass$1.class,因为 IBiLink 是私有(private)的。

再一次,java reflection tutorial此时指定

Since the inner class's constructor references the private constructor of the enclosing class, the compiler must generate a package-private constructor.

在我们的例子中,我们没有明确地看到任何构造函数调用,但我们有这一行

public static class BiNode extends Sub.IBiLink { }

让我们尝试编译这段代码,看看会发生什么

class EnclosingClass
{
//public static class BiNode extends Sub.IBiLink { }
private static class Sub
{
private static class IBiLink
{
}
}
}

未生成 EnwritingClass$1.class

<小时/>

调试时注意到的更多细节

改变

private static class IBiLink

protected static class IBiLink

请注意,编译时,未创建 EnlookingClass$1.class

为什么保护类没有生成合成类?

仅仅是因为在保护类时,您可以隐式访问每个父类(super class)。

<小时/>

为什么 Eclipse 编译器不生成合成类?

Eclipse 使用它内置的编译器,您可以配置它的严重级别。

默认情况下,对封闭类型的不可访问成员的访问设置为忽略,如下图所示。

enter image description here

例如将其更改为警告,您将收到以下消息。

enter image description here

这让我相信 Eclipse 虽然不会创建其他类,但会模拟它来模拟合成成员。

关于java - 为什么编译包含静态嵌套类的类会创建一个名为 "EnclosingClass$1"的新 .class 文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59173558/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com