« June 2006 »
SunMonTueWedThuFriSat
    
1
2
3
4
5
6
8
9
10
11
12
13
15
17
18
20
21
23
25
26
 
       
Today
XML

Blog::Navigation

GetJava Download Button
Get the Source
Personal Blog

Blog::Referers

Today's Page Hits: 1128

Powered by Roller Weblogger.
« Previous day (Jun 20, 2006) | Main | Next day (Jun 22, 2006) »
20060622 Thursday June 22, 2006

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.



( Jun 22 2006, 10:27:32 PM IST ) Permalink Comments [2] del.icio.us | furl | simpy | slashdot | technorati | digg

Copyright (C) 2005, A. Sundararajan's Weblog