X
  • Java |
    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.

Join the discussion

Comments ( 2 )
  • Fabdouglas Friday, June 23, 2006
    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.
  • Fabdouglas Friday, June 23, 2006
    This seems to be a very good optimisation!
    - avoid useless class initalisation until the class is really used.
    - improved performance for class literals
Please enter your name.Please provide a valid email address.Please enter a comment.CAPTCHA challenge response provided was incorrect. Please try again.Captcha

Recent Content

Oracle

Integrated Cloud Applications & Platform Services