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

Java枚举是抽象类,它如何创建自己的实例,java,enums,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.hom

正如我所知,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);
公共抽象类com.tonyzhai.homotation.TestEnum扩展了java.lang.Enum{
公共静态期末考试com.tonyzhai.homogy.TestEnum a;
public static com.tonyzhai.homogy.TestEnum[]value();
代码:
0:getstatic#2//字段$value:[Lcom/tonyzhai/homography/TestEnum;
3:invokevirtual#3//Method“[Lcom/tonyzhai/homography/TestEnum;”。克隆:()Ljava/lang/Object;
6:checkcast#4//class“[Lcom/tonyzhai/Homegram/TestEnum;”
9:轮到你了
public static com.tonyzhai.homogy.TestEnum valueOf(java.lang.String);

因此,它不能实例化,我的问题是抽象必须是没有实例的,所以如果使用Enum实现单例模式,它如何创建自己的实例?

是的,Enum是抽象的,但您不能实际扩展它,除非某些特殊情况,请参阅以获取更多信息。

当您声明
Enum
时,编译器将我将填写某些方面来履行合同。例如,它将添加一个
YourEnumType[]values()
和一个
YourEnumType valueOf(String)
方法

它还将使您的构造函数
私有
,无论您是否声明它,并且它将添加隐式
int
String
参数,这些参数的参数将传递给超级构造函数。这些参数匹配名称和序号,并且当常量为cre时,编译器也将插入相应的参数艾德

例如:

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]);
    }
}
将打印

publicstaticvoidaxis.main(java.lang.String[])
公共静态轴[]轴值()
公共静态Axis.valueOf(java.lang.String)
public Axis Axis.getOther()
建造商:
私有轴(java.lang.String、int、boolean)
因此,您可以看到编译器添加的方法以及构造函数是
private
并且具有附加参数。但是,请注意,这取决于编译器,它在何处以及以何种顺序添加这两个参数。由于构造函数是
private
并且仅在类本身中使用,因此没有兼容性要求我了解初始化是如何工作的


此外,以反射方式获取
构造函数
不允许您构造其他实例。反射实现认识到这是一个
枚举
,并拒绝此类尝试。您必须深入实现以使这些事情成为可能,但这与的意图背道而驰ode>enums无论如何。

如果你能展示Java源代码,那会很有帮助……据我所知,一个简单的enum最终不会生成一个抽象类。你为什么要查看Java反汇编程序的输出?源代码是什么?Java中的enum实例总是在声明它们时实例化(也就是调用构造函数的时候).确实是抽象的,但这与此无关。@dasblinkenlight:我认为
enum
类的实现是抽象的,当且仅当单个枚举常量重写顶级枚举类型的行为时。所有枚举都隐式扩展
java.lang.enum
。是的,但这与实际情况略有不同我在枚举中添加空构造函数,然后反射并调用newInstance()方法,但它抛出NoSuchMethodException,它说我只有enmu(字符串,int)构造函数,但不是我的空构造函数。这就是问题所在。无论您如何定义构造函数,您都将始终拥有两个附加参数。但原则上,对于生成的签名没有标准。理论上,在二进制级别实现它还有其他可能性。您不能调用构造函数refle不管怎么说,都是积极的。