Foo.class does not initialize class Foo!

If you are getting Class object a class using Foo.class construct ("class literals"), the class Foo is not initialized - i.e., the static initializer of the class will not called at that point.


class Main {
  public static void main(String[] args) {
     System.out.println(Foo.class);
  }
}

class Foo {

   static {
     System.out.println("Initializing Foo..");
   }
}

When we compile and run the above Main class with JDK 1.5, we get the following output (I got this on my PC)

D:\\>java -cp . Main
class Foo

We don't see "Initializing Foo.." in the output! -- because Foo.class does not initialize the class Foo. But, if we compile the classes with the command

D:\\>javac -source 1.4 -target 1.4 Main.java

Now, if we run the class,

D:\\>java -cp . Main
Initializing Foo..
class Foo

This time class Foo is initialized! And we get the same result with JDK 1.4.2 - i.e., if you JDK 1.4.2's javac, we see that classFoo is initialized. What is happening...??

Before 1.5, javac compiled Foo.class construct by using Class.forName(String) method:


D:\\>javap -c Main
Compiled from "Main.java"
class Main extends java.lang.Object{
static java.lang.Class class$Foo;

Main();
  Code:
   0:   aload_0
   1:   invokespecial   #6; //Method java/lang/Object."<init>":()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$Foo:Ljava/lang/Class;
   6:   ifnonnull       21
   9:   ldc     #9; //String Foo
   11:  invokestatic    #10; //Method class$:(Ljava/lang/String;)Ljava/lang/Class;
   14:  dup
   15:  putstatic       #8; //Field class$Foo:Ljava/lang/Class;
   18:  goto    24
   21:  getstatic       #8; //Field class$Foo: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."<init>":()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


}

Starting from 1.5, javac uses ldc_w instruction to compile Foo.class

D:\\>javap -c Main
Compiled from "Main.java"
class Main extends java.lang.Object{
Main();
  Code:
   0:   aload_0
   1:   invokespecial   #1; //Method java/lang/Object."<init>":()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 Foo
   6:   invokevirtual   #4; //Method java/io/PrintStream.println:(Ljava/lang/Obj
ect;)V
   9:   return

}

The ldc_w instruction for class literals does not initialize the class. Is the behaviour of 1.5 wrong? i.e., violation of Java Language Spec? No! The language specification for initialization has not changed. It never listed class literal evaluation as an initialization trigger. Class.forName(String) method does initialize the class and therefore translating Foo.class with with Class.forName(String) resulted in the (unwanted) initialiazation of Foo. If you want the old behaviour you may want to use the workaround documented in 5.0 Compatibility notes.

Comments:

This seems to be a very good optimization : - avoid useless class initalisation util the class is really used. - since 5.0 uses "ldc_w" instruction, this improves performance.

Posted by Fabdouglas on June 23, 2006 at 05:54 AM IST #

This seems to be a very good optimisation! - avoid useless class initalisation until the class is really used. - improved performance for class literals

Posted by Fabdouglas on June 23, 2006 at 05:58 AM IST #

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