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.

Comments:

Post a Comment:
Comments are closed for this entry.
About

sundararajan

Search

Archives
« April 2014
SunMonTueWedThuFriSat
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today
Bookmarks
Links

No bookmarks in folder

Blogroll

No bookmarks in folder

News

No bookmarks in folder