Java Enum是抽象类,它如何创建自己的实例

时间:2015-09-24 18:51:36

标签: java enums

据我所知,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模式,它如何创建自己的实例?

2 个答案:

答案 0 :(得分:3)

是Enum是抽象的,但除了某些特殊情况外,您无法实际扩展它,有关详细信息,请参阅here

答案 1 :(得分:1)

当您声明enum时,编译器将填写某些方面以履行合同。例如。它会添加YourEnumType[] values()YourEnumType valueOf(String)方法。

它也会使你的构造函数private,无论你是否声明它,它将添加隐式intString参数,其参数传递给超级构造函数{{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的意图。