问题
Below is the code that defines class type:
package annotationtype;
public class Example {
public static void main(String[] args){
}
}
that gets functionally compiled by javac to:
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){}
}
My major focus is on the Class<annotationtype.Example> class static member variable in the above code. In addition, this member variable Class<annotationtype.Example> class is actually pointing to an object of type class Class that maintains meta data of class Example after class Example gets loaded into memory.
Is my understanding correct?
回答1:
Class literals are part of the language specification as noted in JLS 15.8.2
A class literal is an expression consisting of the name of a class, interface, array, or primitive type, or the pseudo-type void, followed by a '.' and the token class.
The type of C.class, where C is the name of a class, interface, or array type (§4.3), is Class<C>.
The type of p.class, where p is the name of a primitive type (§4.2), is Class<B>, where B is the type of an expression of type p after boxing conversion (§5.1.7).
The type of void.class (§8.4.5) is Class<Void>.
javac doesn't create a static class field for each class, but it will recognize a class literal expression and compile it correctly.
Take for example the class:
public class Hello {
public static void main(String[] args){
Class<?> myClass = Hello.class;
System.out.println("Hello, " + myClass);
}
}
This compiles to (only relevant sections of bytecode included):
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
You can see that javac has put a reference to the Hello class in the constant pool and then loaded that constant when I refer to it in main.
回答2:
If by "functionally compiled" you mean that the class "field" is available to you without you explicitly declaring it, then you are correct. Of course, class isn't a field, it's a class literal in the java language.
Furthermore, if we compile javac Example.java then disasemble javap -c Example we are left with this:
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
}
note that there is no reference to class in this dissembled code. On the other hand, the default constructor Example() does magically appear so, it is fair to say that
public class Example {
public static void main(String[] args){
}
}
compiles to
public class Example {
public Example(){}
public static void main(String[] args){
}
}
来源:https://stackoverflow.com/questions/31185187/in-java-what-does-such-class-type-compile-to