I have some doubt regarding how class variable gets initialized, both static and non static. I mean, suppose I have a class like below.

public class MyClass{
    public static HashMap<String,Buddy> buddiesMap= new HashMap<String,Buddy>();
    public static ArrayList<String> buddiesList=new ArrayList<String>();
    public static HashMap<String,ImageIcon> avatarMap=new HashMap<String, ImageIcon>();
    public static ServerConnection con=new ServerConnection();

    public MyClass(){

    }
}

Now Suppose I access "con" object from somewhere outside this class and I never created any instance or initialized MyClass before. Like I write:
ServerConnection c=MyClass.con;

Now will the other static members also get initialized automatically when for the first time I accessed a static member among them? or they get initialized only when we get them into reference?

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.

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().

As I understood from s.o.s and thekashyap that static fields are not initialized when the class or any static field is accessed for the first time but it is initialized by the classloader.

If I'm understood it right, then when does this class loading process actually takes place? is this happens when the jvm loads all the classes? I mean are these static fields gets initialized right then?

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.

Edited 5 Years Ago by ~s.o.s~: n/a

Comments
Thanks for directing towards specification

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..

I think I almost got it, specification tell 5 ways by which the initialization of the class takes place. Almost all ways described need something to happen with the class or it static field or methods for the initialization to take place just prior to them.

But Kashyap, I can't understand what is the role of the class loader here in initialization. You are saying the initialization takes place when the class is loaded, specification says:

a class loader may cache binary representations of classes and interfaces, prefetch them based on expected usage, or load a group of related classes together.

Is the class loader behind all this initialization process, if yes, please elaborate

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.

Edited 5 Years Ago by thekashyap: n/a

Comments
Thanks for explaining

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.

Ok thanks for this explanation. Getting it very clear now. Actually I was thinking till now that JVM loads all the classes linked with a program or project in a one go. So I was confused that what is the role of classloader afterwards as all the classes are already been loaded when the program started its execution.

And yeah, it is definitely implicit initialization then.Right?

Edited 5 Years Ago by warlord902: n/a

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. :-)

Edited 5 Years Ago by ~s.o.s~: n/a

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. :-)

Yeah, its true that if a class loads then it is not necessary that it will also get initialized. As you mentioned with the case of final fields or with interfaces. You are right to your point, they are two different things.

>>>> 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.

This question has already been answered. Start a new discussion instead.