在java中,这样的枚举类型编译成什么?

In java, What does such enum type compile to?

下面是定义枚举类型的代码。

enum Company{
    EBAY(30), PAYPAL(10), GOOGLE(15), YAHOO(20), ATT(25);
    private int value;

    private Company(int value){
        super(this.name()); 
        this.value = value;
    }

    public int getValue(){
        return value;
    }
}

内部编译为,

final class Company extends Enum<Company>{
    public final static Company EBAY = new Company(30);
    public final static Company PAYPAL = new Company(10);
    public final static Company GOOGLE = new Company(15);
    public final static Company YAHOO = new Company(20);
    public final static Company ATT = new Company(25);

    private int value;

    private Company(int value){
        super(this.name(),Enum.valueOf(Company.class, this.name()));
        this.value = value;
    }

    public int getValue(){
        return value;
    }
}

我的理解正确吗?

功能上,是的。字面意思是不(一方面你不能明确地 sub-class Enum)。 enum(s) 有一个 toString。并且您的 enum 不是有效代码(您不能调用 super())并且 getValue 需要 return 类型。

enum Company{
    EBAY(30), PAYPAL(10), GOOGLE(15), YAHOO(20), ATT(25);
    private int value;

    private Company(int value){
        this.value = value;
    }

    public int getValue(){
        return value;
    }
}

如果您删除对 super 的调用,这是非法的并且 this.name 作为 super 的参数也是非法的,编译它并在 class 上编译 运行 javap,这是输出:

$ /usr/lib/jvm/java-7-oracle/bin/javap -p Company.class 
Compiled from "Company.java"
final class Company extends java.lang.Enum<Company> {
  public static final Company EBAY;
  public static final Company PAYPAL;
  public static final Company GOOGLE;
  public static final Company YAHOO;
  public static final Company ATT;
  private int value;
  private static final Company[] $VALUES;
  public static Company[] values();
  public static Company valueOf(java.lang.String);
  private Company(int);
  public int getValue();
  static {};
}

这是静态的字节码,其中的一部分

static {};
  flags: ACC_STATIC
  LineNumberTable:
    line 2: 0
    line 1: 75
  Code:
    stack=5, locals=0, args_size=0
       0: new           #4                  // class Company
       3: dup           
       4: ldc           #8                  // String EBAY
       6: iconst_0      
       7: bipush        30
       9: invokespecial #9                  // Method "<init>":(Ljava/lang/String;II)V
      12: putstatic     #10                 // Field EBAY:LCompany;

几乎,您的第二个片段确实很好地代表了编译器(字节码)内部生成的内容,但是,它并不完全相同。

编译枚举将包含 ACC_ENUM 标志,表示此 class 或其超级 class 被声明为枚举类型,并将被 JVM 视为枚举类型。

你的第二个片段不会(假设它会编译)在字节码中包含这个标志:


枚举

final class Company extends java.lang.Enum<Company>
      minor version: 0
      major version: 52
      flags: ACC_FINAL, ACC_SUPER, ACC_ENUM

CLASS

final class Company
  minor version: 0
  major version: 52
  flags: ACC_FINAL, ACC_SUPER

至于你的其余逻辑(仍然假设它会编译)是正确的。在内部,枚举将表示为扩展 java.lang.Enumfinal class。但是,请注意,您不能自己直接扩展 java.lang.Enum,因为这些东西是由编译器在创建枚举时完成的,如果您尝试自己做,会导致编译错误。