In studying for the Java certification test I learned that static initialization blocks run once when the class is loaded, in order of appearance within the source code, that instance initialization blocks run each time an instance is created, and that code in constructors runs each time an instance is created after that. To test that I created a class with some static and instance init blocks and a contructor with print stuff. Everything worked as expected -- except I thought "loaded" meant just at runtime, but I guess it happens when the first instance is created, since I don't get any output at all unless I create at least 1 instance of the class. Then I tried the same with an enum and the order was all off. First, the initialization blocks run one time for each value the enum has when the enum is first referenced in code, secondly -- the init blocks marked static run after what I assumed were instance init blocks! This is the opposite of what I expected. Here is a breakdown of my questions.
- Why do the init blocks marked static run last in an enum?
- Can an enum have instance init blocks?
- Why do the blocks I thought were instance init blocks run only once when the enum is loaded and not each time a new enum value is referenced?
- Class static init blocks run when a class is "loaded". What does loaded mean? Does it occur just once when an object is instantiated in the class?
Thanks! This is very confusing to me.
public class EnumInit {
public static void main(String[] args) {
System.out.println(Color.RED.toString() + " Main");
MyInit myInit = new MyInit();
System.out.println(Color.BLUE.toString() + " Main");
MyInit mySecondInit = new MyInit();
}
}
enum Color {
RED, BLUE, GREEN;
String instanceVar = "Enum Instance Variable Text";
static { System.out.println("Enum Static init block 1"); }
{ System.out.println("Enum Instance init block 1"); }
static { System.out.println("Enum Static static init block 2"); }
Color() {
System.out.println(instanceVar);
System.out.println("Enum String Literal");
}
{ System.out.println("Enum Instance init block 2"); }
}
class MyInit {
String instanceVar = "Class Instance Variable Text";
static { System.out.println("Class Static init block 1"); }
{ System.out.println("Class Instance init block 1"); }
static { System.out.println("Class Static static init block 2"); }
MyInit() {
System.out.println(instanceVar);
System.out.println("Class String Literal");
}
{ System.out.println("Class Instance init block 2"); }
}
The Java Language Specification says this about
enum
constantsSo
is actually
which will get evaluated before the
static
blocks you have.See above.
Yes, compile your code and you will see.
Enum constants are created (instantiated) once the enum type is initialized. You don't create a new
enum
any time you doYou are just referencing an already created, existing object.
When a class is referenced in the JVM for the first time, it is loaded by the
ClassLoader
and initialized. Read more about it here.