0
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 ?

1
  • 1
    VAR2 is a constant value but VAR1 is a simple static variable. That means VAR1 will be initialized after stObj is initialized. That's why VAR1 is 0 [default int init value] at the first call, and 10 after the second call. Commented Mar 30, 2012 at 12:58

4 Answers 4

5

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.

Sign up to request clarification or add additional context in comments.

Comments

3

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.

4 Comments

So you mean to say at compile time VAR2 is assumed as constant?
@amicngh: It's not a matter of assumption - it's a matter of following the JLS. The variable is static and final, it's of a primitive type, and the initialization expression is a compile-time constant expression; see docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.28
@JonSkeet, you're right, but I think there's more to it in this question (regarding initialisation order).
@Bruno: Well my answer is about why VAR1 and VAR2 behave differently. I was hoping the OP could figure the rest out - Boris's answer covers it nicely.
0

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

2 Comments

But nobody is changing any variable ?
The variable VAR is initially 0 before it can be set to 10.
0

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

Comments

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.