amicngh
amicngh

Reputation: 7899

Java difference between static and final static variable initialization

public class StaticTest {

    private static StaticTest stObj=new StaticTest();
    private static int VAR1=10;
    private static final int VAR2=20;

    public StaticTest() {

        System.out.println("Var1 : "+VAR1);
        System.out.println("Var2 : "+VAR2);
    }

    public static void main(String[] args) {
        System.out.println("VAR1 after constrution : "+StaticTest.VAR1);
    }

}

Output :

Var1 : 0 Var2 : 20 VAR1 after constrution : 10

Why is this different behavior for VAR1 and VAR2 ?

Upvotes: 0

Views: 2289

Answers (4)

Jon Skeet
Jon Skeet

Reputation: 1499880

VAR2 is a compile-time constant, so its value is "baked in" to every call site. It therefore doesn't matter that you use it before you would expect to see it initialized. If you change it to something which isn't a constant as far as the compiler is concerned, e.g.

private static final int VAR2 = "xyz".length();

then you'll see the same behaviour as for VAR1 (in terms of the output).

See section 15.28 of the JLS for more information about constant expressions.

Upvotes: 3

Bruno
Bruno

Reputation: 122609

VAR2 cannot be changed one the class has been initialised, whereas any instance of the class can change VAR later on.

The issue here is that you're referring to the variable before it has been fully initialised.

private static StaticTest stObj=new StaticTest();
private static int VAR1=10;
private static final int VAR2=20;

You're creating an instance of the class when loading the class itself, before the other static members have been initialised.

Check the Java Language Specifications for more details (Chapter 12).

(Generally, creating an instance of the class during its own construction will lead to problems: you should avoid this.)

Upvotes: 0

Boris Strandjev
Boris Strandjev

Reputation: 46943

The static fields get initialized one by one in order of declaration. In your particular case you initialize StaticTest stObj first. This gets executed before the initialization of the VAR1. Thus VAR1 bears its default value when printing.

However VAR2 is compile-time constant, thus the compiler optimizes its initialization and it is initialized first. That way one of the variables is initialized by the time you call the constructor, the other -not.

Upvotes: 5

adarshr
adarshr

Reputation: 62573

VAR1 can be changed, VAR2 can't.

Try this:

private static int VAR1=10;
private static final int VAR2=20;

public static void main(String[] args) {
    VAR1 = 25;
    VAR2 = 35; // You'll find a compilation error here.
}

Upvotes: 0

Related Questions