To understand why you're seeing the constructor called multiple times, we'll have a look at what happens behind the screen.
Starting with a simple Enums.java:
enum Enums { A, B; }
We'll compile, then immediately decompile to see what Java actually does with it internally:
javac Enums.java && javap -c Enums
which gives the following result (I'll cut a lot for brevity, but keep the important bits):
final class Enums extends java.lang.Enum<Enums> {
public static final Enums A;
public static final Enums B;
...
static {}; //<-- Static initialiser
Code:
//Construct a new object, assign it to A
0: new #4 // class Enums
3: dup
4: ldc #7 // String A
6: iconst_0 // 0
7: invokespecial #8 // Method "<init>":(LString;I)V <-- calls the parent constructor with "string A" and "const 0" above
10: putstatic #9 // Field A:LEnums;
//Construct another, assign it to B
13: new #4 // class Enums
16: dup
17: ldc #10 // String B
19: iconst_1 // 1
20: invokespecial #8 // Method "<init>":(LString;I)V <-- calls the parent constructor with "string B" and "const 1 above"
23: putstatic #11 // Field B:LEnums;
...
45: return
}
What you have there are:
- Two
public static final fields called A and B, and
- A static initialiser, which contains two
new statements that constructs both A and B.
- As all enums are descended from
java.lang.Enum<>, the two new calls also invoke the parent's constructor: protected Enum(String name, int ordinal) to give A and B a name and a numeric order.
The static initialiser you see above is the cause of you seeing multiple calls to your println(), even though you are only using one of the enums. The nature of static initialisers is that it gets called when you first use a class.
And as you can see in the code produced by the compiler, it will immediately construct both A and B (and C in your case), when you attempt to use your enum.