Mohasin Ali
Mohasin Ali

Reputation: 4015

Why java static variable is not updating?

I have a Class called Color in which there are three static Objects (instantiating with the same class itself) and a int type (called i) variable. When I Run the Class, the 'i' variable is increments in the Constructor, but it is not persisting in memory , please explain this below code

package test;
public class Color
{
     public static  Color RED = new Color();
     public static final Color BLUE = new Color();
     public static final Color GREEN = new Color();
     static int i=0;

     Color(){
         System.out.println("Incrementing 'i'  here  "+(++i));
     }

     public static void main(String[] args) {
         System.out.println("The 'i' variable is not incremented here, it still shows '0' ,  'i' is: "+ Color.i );  // line 14 
        Color x = new Color();
        System.out.println(x.i);
    }
}

The out is as follow:

Incrementing 'i'  here  1
Incrementing 'i'  here  2
Incrementing 'i'  here  3
The 'i' variable is not incremented here, it still shows '0' ,  'i' is: 0
Incrementing 'i'  here  1
1

Upvotes: 4

Views: 8056

Answers (2)

Ted Hopp
Ted Hopp

Reputation: 234807

When a class is loaded and linked, its static fields are all initialized to their default values. Once that is done, the static field initializers are executed in the order they appear in the file, thus completing the initialization of the class. All this happens before any code defined in that class executes. So what's happening here is:

  1. RED, GREEN, BLUE, and i are initialized to their default values (null for the Color fields and 0 for i). Note that this is independent of any initializers.
  2. The initializer for field RED (RED = new Color()) executes. As a side effect, i is incremented to 1.
  3. The initializer for field BLUE executes and i is incremented to 2.
  4. The initializer for field GREEN executes and i is incremented to 3.
  5. The initializer for the static field i executes and i is assigned the value 0.
  6. The main() method executes and produces the results consistent with i being 0 when main() begins execution.

You can read the gory details of all this in Chapter 12 of the Java Language Specification (JLS) and Chapter 5 of the Java Virtual Machine Specification.

You can get the output you expected simply by move the declaration of i to be ahead of the Color fields:

 static int i=0;
 public static  Color RED = new Color();
 public static final Color BLUE = new Color();
 public static final Color GREEN = new Color();

Then the output will be:

Incrementing 'i' here 1
Incrementing 'i' here 2
Incrementing 'i' here 3
The 'i' variable is not incremented here, it still shows '0' , 'i' is: 3
Incrementing 'i' here 4
4

Note that the final modifiers have no effect on the order of initialization here because GREEN and BLUE are not "constant variables" according to the definition of that term in the JLS. A constant variable (an unfortunate pairing of words) is a primitive or String variable that is both declared final and initialized to a constant expression. In this case, new Color() is not a constant expression and Color is not an appropriate type for a constant variable. See, for instance, §4.12.4 of the JLS.

Upvotes: 8

Debapriya Biswas
Debapriya Biswas

Reputation: 1339

Class Initialization proceeds top to bottom .When we initialize Color we create a new Color .In order to create a new Color we also have to initialize Color. That's called recursive initialization and what the system does is simply ignores the recursive initialization and executes new Color(). This class initializer executes by the below sequence top to bottom

  1. public static Color RED = new Color(); this sets static variable i to 1.

  2. public static final Color BLUE = new Color(); this increments static variable i to 2

  3. public static final Color GREEN = new Color(); this increments static variable i to 3

  4. static int i=0; this sets static variable i back to zero.

Now when the main thread runs.It sees the static variable to 0 and increments to 1.

As a counter example try replacing static int i=0 to static Integer i=new Integer(0). . This will throw a NullPointerException . This is because at class initialization time when public static Color RED = new Color(); executes it sees the i as null , because i has not been initialized by then, resulting in NullPointerException

Upvotes: 0

Related Questions