Yes, the class initialization has to complete (executing static initialize blocks and initializing static fields) before you can access the 'con' static field which implies initializing the other static fields. But there is an exception to this rule: the class initialization does *not* take place if you access a "constant variable" (final declaration of primitives of string in your class). E.g.
public class Test {
public static void main(final String[] args) {
System.out.println(StatKlass.THE_ONE); // will *not* cause initialization of static fields (e.g. conn)
System.out.println(StatKlass.NOT_THE_ONE); // will cause initialization of static fields (e.g. conn)
}
}
class StatKlass {
public static final int THE_ONE = 1;
public static int NOT_THE_ONE = 0;
public static ServerConnection conn = new ServerConnection();
}
Many people get confused between class loading and class initialization and assume that all static elements would be initialized when the class is accessed for the first time, which isn't the case as we see above.
Also, if your class implements an interface and it has "fields" (public static final by default), those won't be initialized when the class is initialized. They have to be explicitly referenced for the initialization to take place. Same with super interfaces of an interface.
~s.o.s~
Failure as a human
11,938 posts since Jun 2006
Reputation Points: 3,281
Solved Threads: 734
Static members are init'd when teh class is loaded.
Classloader's forName() method is the one that is supposed to do it.
Exception is when you explicitly ask classloader NOT to init the class but just load it by passing false as second argument to the overloaded forName() .
thekashyap
Practically a Posting Shark
811 posts since Feb 2007
Reputation Points: 254
Solved Threads: 75
You've got things mixed up; re-read my post and try out the example. Kashyap provided a way for "explicitly" initializing a class whereas I talk about implicit initialization in my first post. The entire process is mentioned in the specification .A class or interface type T will be initialized immediately before the first occurrence of any one of the following:
T is a class and an instance of T is created.
T is a class and a static method declared by T is invoked.
A static field declared by T is assigned.
A static field declared by T is used and the field is not a constant variable (§4.12.4).
T is a top-level class, and an assert statement (§14.10) lexically nested within T is executed.
So basically, whenever you try accessing a static field (except for constant variables), the class would be initialized.
~s.o.s~
Failure as a human
11,938 posts since Jun 2006
Reputation Points: 3,281
Solved Threads: 734
I was waiting for SoS to to contradict my statements and give reasons for it. :)
Here is what the spec says:
"
A class or interface type T will be initialized immediately before the first occurrence of any one of the following:T is a class and an instance of T is created.
T is a class and a static method declared by T is invoked.
A static field declared by T is assigned.
A static field declared by T is used and the field is not a constant variable (§4.12.4).
T is a top-level class, and an assert statement (§14.10) lexically nested within T is executed.
"
Most of the bullets implicitly lead to class loading if the class is not already loaded...
Lets wait for SoS to comment now..
thekashyap
Practically a Posting Shark
811 posts since Feb 2007
Reputation Points: 254
Solved Threads: 75
Well, what you ask is a very basic question, so a bit difficult to answer in short. I'll try:
ClassLoader(s) are used by JVM to load classes as and when they're used (one of the 5) by the code being executed.
Given a fully qualified class name, what it does is:
- locate the class in the classpath.
- reads the .class file and load it into JVM memory.
- initialize (optionally as we discussed)
- it also takes care of security etc, but not relevant to current discussion.
Usually you never bother abt them, as the default class loader impl packaged with the JRE is good enough. It does what you need transparently.
Most of the JVM code uses ClassLoader. E.g. every time you access a class by doing a "new XXX()" JVM would call ClassLoader to load XXX if it's not already loaded. Same goes for other 5 options. Or in your words: "something to happen with the class or it static field or methods" ==> To make any of this to happen, JVM has to call ClassLoader if the class in question is not already loaded.
I suggest you put a break point in teh forName() method in Eclipse and debug a hello world program step-by-step. You'll see what all it does.
Hope it's clearer now.
thekashyap
Practically a Posting Shark
811 posts since Feb 2007
Reputation Points: 254
Solved Threads: 75
You might find it helpful if you think of class loading and initialization as two different things. For e.g. when I write "StatKlass.THE_ONE", the class-loader loads the binary representation of the class StatKlass (i.e. the .class file) but *doesn't* initialize it.
EDIT:
> Lets wait for SoS to comment now..
I already have given my comments. :-)
~s.o.s~
Failure as a human
11,938 posts since Jun 2006
Reputation Points: 3,281
Solved Threads: 734
>>>> Lets wait for SoS to comment now..
>> I already have given my comments. :-)
It's quite a chance that twice in a post both of us were posting at teh same time and you clicked post before I did.
Please ignore.
thekashyap
Practically a Posting Shark
811 posts since Feb 2007
Reputation Points: 254
Solved Threads: 75