在java中,这样的类类型编译为什么



以下是定义class类型的代码:

package annotationtype;
public class Example {
    public static void main(String[] args){

    }
}

javac功能性地编译为:

public class annotationtype.Example{
    public static Class<annotationtype.Example> class;
    {
        class = Class.forName("annotationtype.Example")
    }
    public annotationtype.Example(){}
    public static void main(java.lang.String[] args){}
}

我主要关注的是上面代码中的Class<annotationtype.Example> class静态成员变量。此外,该成员变量Class<annotationtype.Example> class实际上指向class Class类型的对象,该对象在class Example加载到内存中之后维护class Example的元数据。

我的理解正确吗?

类文字是JLS 15.8.2 中指出的语言规范的一部分

类文字是一个表达式,由类、接口、数组或基元类型的名称或伪类型void组成,后跟"以及令牌类。

C.class的类型,其中C是类、接口或数组类型(§4.3)是Class<C>。

p类的类型,其中p是基元类型的名称(§4.2),是类<B>;,其中B是在装箱转换(§5.1.7)。

无效类别的类型(§8.4.5)为类别<无效>。

javac不会为每个类创建一个静态的class字段,但它会识别类的文字表达式并正确编译它。

以类为例:

public class Hello {
        public static void main(String[] args){
                Class<?> myClass = Hello.class;
                System.out.println("Hello, " + myClass);
        }
}

这将编译为(仅包括字节码的相关部分):

public class Hello   minor version: 0   major version: 52   flags:
 ACC_PUBLIC, ACC_SUPER 
Constant pool:    
#1 = Methodref          #11.#20        // java/lang/Object."<init>":()V    
#2 = Class              #21            // Hello
......
public static void main(java.lang.String[]);
descriptor: ([Ljava/lang/String;)V
flags: ACC_PUBLIC, ACC_STATIC
Code:
  stack=3, locals=2, args_size=1
     0: ldc           #2                  // class Hello
     2: astore_1

您可以看到,javac在常量池中放置了对Hello类的引用,然后在main中引用该常量时加载了该常量。

如果您所说的"功能编译"是指class"字段"在没有明确声明的情况下对您可用,那么您是正确的。当然,class不是一个字段,它是java语言中的一个类文字。

此外,如果我们编译javac Example.java,然后再组装javap -c Example,我们只剩下以下内容:

Compiled from "Example.java"
public class Example {
  public Example();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: return
  public static void main(java.lang.String[]);
    Code:
       0: return
}

请注意,在这个分解的代码中没有引用class。另一方面,默认构造函数Example()确实神奇地出现了,所以可以公平地说

public class Example {
    public static void main(String[] args){
    }
}

编译为

public class Example {
    public Example(){}
    public static void main(String[] args){
    }
}

相关内容

  • 没有找到相关文章