Reputation: 117
As I know, Enum is abstract class, I write an Enum, then I do javap command, I got:
public abstract class com.tonyzhai.homework.TestEnum extends java.lang.Enum<com.tonyzhai.homework.TestEnum> {
public static final com.tonyzhai.homework.TestEnum a;
public static com.tonyzhai.homework.TestEnum[] values();
Code:
0: getstatic #2 // Field $VALUES:[Lcom/tonyzhai/homework/TestEnum;
3: invokevirtual #3 // Method "[Lcom/tonyzhai/homework/TestEnum;".clone:()Ljava/lang/Object;
6: checkcast #4 // class "[Lcom/tonyzhai/homework/TestEnum;"
9: areturn
public static com.tonyzhai.homework.TestEnum valueOf(java.lang.String);
so, it cannot instantiation, my question is that abstract must be has no instance, so if use Enum implement Singleton pattern, how it create its own instance?
Upvotes: 3
Views: 472
Reputation: 298203
When you declare an enum
, the compiler will fill in certain aspects to fulfill the contract. E.g. it will add a YourEnumType[] values()
and a YourEnumType valueOf(String)
method.
It will also make your constructor private
, regardless of whether you declared it, and it will add implicit int
and String
parameters whose arguments get passed to the super constructor Enum(String, int)
. These match the name and ordinal and the compiler will also insert the appropriate arguments when the constants are created.
For example:
public enum Axis {
HORIZONTAL(true), VERTICAL(false);
private boolean isHorizontal;
Axis(boolean horizontal) {
isHorizontal=horizontal;
}
public Axis getOther() {
return isHorizontal? VERTICAL: HORIZONTAL;
}
public static void main(String... arg) {
for(Method m: Axis.class.getDeclaredMethods())
System.out.println(m);
System.out.println("constructor:");
System.out.println(Axis.class.getDeclaredConstructors()[0]);
}
}
will print
public static void Axis.main(java.lang.String[])
public static Axis[] Axis.values()
public static Axis Axis.valueOf(java.lang.String)
public Axis Axis.getOther()
constructor:
private Axis(java.lang.String,int,boolean)
So you see the compiler added methods as well as the constructor being private
and having the additional parameters. Note, however, that it is up to the compiler, where and in which order it adds these two parameters. Since the constructor is private
and only used within the class itself, there is no compatibility requirement about how the initialization exactly works.
Further, getting the Constructor
reflectively doesn’t allow you to construct additional instances. The Reflection implementation recognizes that this is an enum
and rejects such attempts. You would have to hack deeper into the implementation to make such things possible, but that’s counteracting the intention of enum
s anyway.
Upvotes: 1
Reputation: 796
Yes Enum is abstract but you cannot actually extend it, except for some special circumstances, see here for more information.
Upvotes: 3