为什么编译包含静态嵌套类的类会创建一个名为"EnclosingClass $ 1"的新.class文件? [英] Why does compiling a class containing static nested classes create a new .class file named "EnclosingClass$1"?

查看:155
本文介绍了为什么编译包含静态嵌套类的类会创建一个名为"EnclosingClass $ 1"的新.class文件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在下面的代码中:

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

在与其他.class文件一起编译时,我还看到一个名为"EnclosingClass $ 1.class"的文件.为什么会自动创建该文件?怎么了?

On compiling along with other .class files, I also see a file named "EnclosingClass$1.class" .Why has this been automatically created? Whats going on?

推荐答案

首先查看JVM规范中的类访问和属性修改器表.

First have a look at the class access and propery modifier table from the JVM specifications.

请注意ACC_SYNTHETIC标志,该解释指定该解释指示源代码中不存在该标志(简单地说,当编译器生成该类时将添加该标志).

Notice the ACC_SYNTHETIC flag which interpretation specify that it is not present in the source code (in simplier words, it will be added when the class is generated by the compiler).

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

Let's have a look at the bytecode of EnclosingClass$1.class (note that I will paste only the part that matter).

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.

Notice that the access flags of the class contains 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.

确保生成的类是合成类的另一种选择是编译为

An other option to make sure the generated class is synthetic is to compile as

javac -XD-printflat EnclosingClass.java

会产生

/*synthetic*/ class EnclosingClass$1 {
}


太好了,但是为什么要生成一个综合类呢?


Great, but why generate a synthetic class ?

Java反射教程可以帮助我们理解这一点.看看 SyntheticConstructor 班级

The Java reflection tutorial can help us understand this. Have a look at the comments in the SyntheticConstructor class

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

因此,根据评论,由于IBiLink是私有的,因此创建了合成类EnclosingClass$1.class.

So according on the comment, the synthetic class EnclosingClass$1.class was created because IBiLink was private.

再次, java反射教程指定为这一点

由于内部类的构造函数引用了私有构造函数 封闭类的编译器必须生成package-private 构造函数.

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

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

In our case, we do not see explicitely any constructor call, but we have this line

public static class BiNode extends Sub.IBiLink { }

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

Let's try compiling this code and see what happen

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

未生成EnclosingClass$1.class.

调试时注意到更多详细信息

更改

private static class IBiLink

protected static class IBiLink

请注意,编译时不会创建EnclosingClass$1.class.

notice that when compiling, EnclosingClass$1.class is not created.

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

why does protecting the class did not generate a synthetic class ?

这是因为在保护类时,您隐式地可以访问每个超类.

Simply because when protecting the class, you implicitely get access to each of the super classes.

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

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

Eclipse use it built-in compiler, which you can configure it severity level.

默认情况下,如该图所示,对封闭类型的不可访问成员的访问权限设置为 ignore .

By default, Access to a non-accessible member of an enclosing type is set to ignore as you can see on this image.

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

Change it for example to warning and you will get the following message.

让我相信eclipse,altought不会创建另一个类,它将模拟它来模拟合成成员.

which let me believe that eclipse, altought does not create an other class, will emulate it to simulate the synthetic member.

这篇关于为什么编译包含静态嵌套类的类会创建一个名为"EnclosingClass $ 1"的新.class文件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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