Java | Wednesday, December 15, 2004

Class literals in JDK 1.5

class literals allow us to get Class objects of named classes. Before JDK 1.5, class literals were implemented using Class.forName. Example:


public class Main {

public static void main(String[] args) {

// print Class object of Main class

System.out.println(Main.class);

}
}

If we compile Main.java using 1.4.2 or earlier JDK (or use javac -source 1.4 -target 1.4 Main.java with 1.5 JDK) and decompile the resultant class using javap -c Main command, we get the following output.


Compiled from "Main.java"
public class Main extends java.lang.Object{
static java.lang.Class class$Main;
public Main();
Code:
0: aload_0
1: invokespecial #6; //Method java/lang/Object."":()V
4: return
public static void main(java.lang.String[]);
Code:
0: getstatic #7; //Field java/lang/System.out:Ljava/io/PrintStream;
3: getstatic #8; //Field class$Main:Ljava/lang/Class;
6: ifnonnull 21
9: ldc #9; //String Main
11: invokestatic #10; //Method class$:(Ljava/lang/String;)Ljava/lang/Class;
14: dup
15: putstatic #8; //Field class$Main:Ljava/lang/Class;
18: goto 24
21: getstatic #8; //Field class$Main:Ljava/lang/Class;
24: invokevirtual #11; //Method java/io/PrintStream.println:(Ljava/lang/Object;)V
27: return
static java.lang.Class class$(java.lang.String);
Code:
0: aload_0
1: invokestatic #1; //Method java/lang/Class.forName:(Ljava/lang/String;
)Ljava/lang/Class;
4: areturn
5: astore_1
6: new #3; //class java/lang/NoClassDefFoundError
9: dup
10: invokespecial #4; //Method java/lang/NoClassDefFoundError."":()V
13: aload_1
14: invokevirtual #5; //Method java/lang/NoClassDefFoundError.initCause:(Ljava/lang/Throwable;)Ljava/lang/Throwable;
17: athrow
Exception table:
from to target type
0 4 5 Class java/lang/ClassNotFoundException
}

Actually, the source effectively becomes:

public class Main {
static java.lang.Class class$Main;
public static void main(String[] args) {
if (class$Main == null) {
class$Main = class$("Main");
}
System.out.println(class$Main);
}
static Class class$(java.lang.String className) {
try {
return Class.forName(className);
} catch (ClassNotFoundException e) {
throw new NoClassDefFoundError();
}
}
}

With 1.5, a new variant of ldc_w has been defined to implement class literals. This instruction can accept an index of ClassInfo type constant and loads the referred Class object on execution.

If we compile this class with 1.5 JDK and use the command
javap -c Main to decompile, we get the following output


Compiled from "Main.java"
public class Main extends java.lang.Object{
public Main();
Code:
0: aload_0
1: invokespecial #1; //Method java/lang/Object."":()V
4: return
public static void main(java.lang.String[]);
Code:
0: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintStream;
3: ldc_w #3; //class Main
6: invokevirtual #4; //Method java/io/PrintStream.println:(Ljava/lang/Obj
ect;)V
9: return
}

The highlighted ldc_w instruction loads Class object of Main class on expression stack.

Join the discussion

Comments ( 0 )
Please enter your name.Please provide a valid email address.Please enter a comment.CAPTCHA challenge response provided was incorrect. Please try again.Captcha
 

Visit the Oracle Blog

 

Contact Us

Oracle

Integrated Cloud Applications & Platform Services