以下是定义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
的元数据。
我的理解是否正确?
答案 0 :(得分:4)
类文字是JLS 15.8.2
中提到的语言规范的一部分类文字是一个表达式,由类,接口,数组或基本类型的名称或伪类型void组成,后跟“。”。和令牌类。
C.class的类型,其中C是类,接口或的名称 数组类型(§4.3),是Class&lt; C&gt;。
p.class的类型,其中p是基本类型的名称(§4.2), 是Class&lt; B&gt ;,其中B是p后面的类型的表达式 拳击转换(§5.1.7)。
void.class(§8.4.5)的类型是Class&lt; Void&gt ;.
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
中引用它时加载了该常量。
答案 1 :(得分:0)
如果通过“功能编译”表示您可以使用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){
}
}