据我所知,Enum是抽象类,我写了一个Enum,然后我做了javap命令,我得到了:
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);
所以,它无法实例化,我的问题是抽象必须没有实例,所以如果使用Enum实现Singleton模式,它如何创建自己的实例?
答案 0 :(得分:3)
是Enum是抽象的,但除了某些特殊情况外,您无法实际扩展它,有关详细信息,请参阅here。
答案 1 :(得分:1)
当您声明enum
时,编译器将填写某些方面以履行合同。例如。它会添加YourEnumType[] values()
和YourEnumType valueOf(String)
方法。
它也会使你的构造函数private
,无论你是否声明它,它将添加隐式int
和String
参数,其参数传递给超级构造函数{{3 }}。这些与name和ordinal匹配,编译器也会在创建常量时插入适当的参数。
例如:
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]);
}
}
将打印
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)
因此,您会看到编译器添加了方法以及构造函数为private
并且具有其他参数。但请注意,由编译器来决定它添加这两个参数的位置和顺序。由于构造函数是private
并且仅在类本身中使用,因此没有关于初始化如何正常工作的兼容性要求。
此外,反复获取Constructor
不允许您构建其他实例。 Reflection实现认识到这是enum
并拒绝此类尝试。你不得不深入研究实现以使这些事情成为可能,但这无论如何都会抵消enum
的意图。