108

I am wondering when static variables are initialized to their default values. Is it correct that when a class is loaded, static vars are created (allocated), then static initializers and initializations in declarations are executed? At what point are the default values are given? This leads to the problem of forward reference.

Also please if you can explain this in reference to the question asked on Why static fields are not initialized in time? and especially the answer given by Kevin Brock on the same site. I can't understand the 3rd point.

3
  • 2
    Please could your edit your question to include the quote you're referring to. Jan 2, 2012 at 19:13
  • 1
    Have you read the Java language specification? It is a pretty readable document, deliberately so. If you have read that, you might understand what's going on. If not, you can ask a more specific question at the minimum... Jan 2, 2012 at 19:18
  • I think this Q&A is a dup of stackoverflow.com/questions/3499214.
    – Stephen C
    Oct 23, 2018 at 13:17

7 Answers 7

90

From See Java Static Variable Methods:

  • It is a variable which belongs to the class and not to object(instance)
  • Static variables are initialized only once , at the start of the execution. These variables will be initialized first, before the initialization of any instance variables
  • A single copy to be shared by all instances of the class
  • A static variable can be accessed directly by the class name and doesn’t need any object.

Instance and class (static) variables are automatically initialized to standard default values if you fail to purposely initialize them. Although local variables are not automatically initialized, you cannot compile a program that fails to either initialize a local variable or assign a value to that local variable before it is used.

What the compiler actually does is to internally produce a single class initialization routine that combines all the static variable initializers and all of the static initializer blocks of code, in the order that they appear in the class declaration. This single initialization procedure is run automatically, one time only, when the class is first loaded.

In case of inner classes, they can not have static fields

An inner class is a nested class that is not explicitly or implicitly declared static.

...

Inner classes may not declare static initializers (§8.7) or member interfaces...

Inner classes may not declare static members, unless they are constant variables...

See JLS 8.1.3 Inner Classes and Enclosing Instances

final fields in Java can be initialized separately from their declaration place this is however can not be applicable to static final fields. See the example below.

final class Demo
{
    private final int x;
    private static final int z;  //must be initialized here.

    static 
    {
        z = 10;  //It can be initialized here.
    }

    public Demo(int x)
    {
        this.x=x;  //This is possible.
        //z=15; compiler-error - can not assign a value to a final variable z
    }
}

This is because there is just one copy of the static variables associated with the type, rather than one associated with each instance of the type as with instance variables and if we try to initialize z of type static final within the constructor, it will attempt to reinitialize the static final type field z because the constructor is run on each instantiation of the class that must not occur to static final fields.

4
  • 5
    In case of static inner classes, they can not have static fields seems like a typo. Inner classes are non-static. Nov 4, 2014 at 21:58
  • You should use however instead of Although
    – Suraj Jain
    Mar 8, 2017 at 3:18
  • When you fire up a JVM and load a class for the first time (this is done by the classloader when the class is first referenced in any way) any static blocks or fields are 'loaded' into the JVM and become accessible.
    – nhoxbypass
    Jan 28, 2018 at 6:39
  • 1
    Unfortunately this answer contains some factually inaccuracies about when statics are initialized. Please see stackoverflow.com/a/3499322/139985.
    – Stephen C
    Oct 23, 2018 at 13:13
17

Static fields are initialized when the class is loaded by the class loader. Default values are assigned at this time. This is done in the order than they appear in the source code.

15

See:

The last in particular provides detailed initialization steps that spell out when static variables are initialized, and in what order (with the caveat that final class variables and interface fields that are compile-time constants are initialized first.)

I'm not sure what your specific question about point 3 (assuming you mean the nested one?) is. The detailed sequence states this would be a recursive initialization request so it will continue initialization.

10

The order of initialization is:

  1. Static initialization blocks
  2. Instance initialization blocks
  3. Constructors

The details of the process are explained in the JVM specification document.

6

static variable

  • It is a variable which belongs to the class and not to object(instance)
  • Static variables are initialized only once , at the start of the execution(when the Classloader load the class for the first time) .
  • These variables will be initialized first, before the initialization of any instance variables
  • A single copy to be shared by all instances of the class
  • A static variable can be accessed directly by the class name and doesn’t need any object
5

Starting with the code from the other question:

class MyClass {
  private static MyClass myClass = new MyClass();
  private static final Object obj = new Object();
  public MyClass() {
    System.out.println(obj); // will print null once
  }
}

A reference to this class will start initialization. First, the class will be marked as initialized. Then the first static field will be initialized with a new instance of MyClass(). Note that myClass is immediately given a reference to a blank MyClass instance. The space is there, but all values are null. The constructor is now executed and prints obj, which is null.

Now back to initializing the class: obj is made a reference to a new real object, and we're done.

If this was set off by a statement like: MyClass mc = new MyClass(); space for a new MyClass instance is again allocated (and the reference placed in mc). The constructor is again executed and again prints obj, which now is not null.

The real trick here is that when you use new, as in WhatEverItIs weii = new WhatEverItIs( p1, p2 ); weii is immediately given a reference to a bit of nulled memory. The JVM will then go on to initialize values and run the constructor. But if you somehow reference weii before it does so--by referencing it from another thread or or by referencing from the class initialization, for instance--you are looking at a class instance filled with null values.

3
  • 1
    A class isn't marked as initialized until initialization has been completed--doing otherwise wouldn't make sense. Marking as initialized is almost the last step taken. See JLS 12.4.2. Jan 2, 2012 at 20:40
  • @DaveNewton: Once something references the class and starts initializing it, all further references will treat the class as initialized. They won't try to initialize it, and they will not wait for it to be initialized. Hence fields that appear to be not-null from a program's start can actually be null for a time. Not understanding this is what is causing all the confusion. I think it's simplest to say an uninitialized class is "marked" as initialized on the first reference, all other references treat it as intialized, and that's why this happens. Jan 2, 2012 at 22:34
  • A correction to the previous comment: as described Dave Newton's JLS 12.4.2, the class is locked while being initialized. Other threads will wait for the class to be initialized. That doesn't affect this case, however, which all happens in one thread. Jan 2, 2012 at 23:58
4

The static variable can be intialize in the following three ways as follow choose any one you like

  1. you can intialize it at the time of declaration
  2. or you can do by making static block eg:

    static {
            // whatever code is needed for initialization goes here
        }
    
  3. There is an alternative to static blocks — you can write a private static method

    class name {
        public static varType myVar = initializeVar();
    
        private static varType initializeVar() {
            // initialization code goes here
        }
    }
    

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.