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
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:
RED
,GREEN
,BLUE
, andi
are initialized to their default values (null
for theColor
fields and 0 fori
). Note that this is independent of any initializers.- The initializer for field
RED
(RED = new Color()
) executes. As a side effect,i
is incremented to 1. - The initializer for field
BLUE
executes andi
is incremented to 2. - The initializer for field
GREEN
executes andi
is incremented to 3. - The initializer for the
static
fieldi
executes andi
is assigned the value 0. - The
main()
method executes and produces the results consistent withi
being 0 whenmain()
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.