В java, к чему компилируется такой тип перечисления?

Ниже приведен код, определяющий тип перечисления.

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;
    }
}

правильно ли я понимаю?

3 ответов


функционально, да. Буквально нет (вы не можете явно подкласс Enum во-первых). enum(s) есть toString. И ваш enum недопустимый код (вы не можете позвонить super()) и getValue требуется тип возврата.

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;
    }
}

почти, ваш второй фрагмент хорошо представляет то, что внутренне генерируется компилятором (байт-кодом), однако это не совсем то же самое.

скомпилированное перечисление будет содержать ACC_ENUM флаг, который указывает, что этот класс или его суперкласс объявлен как перечисляемый тип и будет рассматриваться как таковой JVM.

ваш второй фрагмент не будет (предположим, что он будет компилироваться) включать этот флаг в байт-код :


перечисление

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

класс

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

что касается остальной части вашей логики (все еще предполагая, что она будет компилироваться), это правильно. Внутренне перечисление будет представлено как final класс, который расширяется java.lang.Enum. Однако, обратите внимание, что вы не можете напрямую выходит java.lang.Enum себя, поскольку этот материал выполняется компилятором при создании перечисления и приведет к ошибке компиляции, если вы попытаетесь это сделать себе.


если вы удалите вызов super что является незаконным и this.name поскольку параметр super также является незаконным, скомпилируйте его и запустите 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;