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

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

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

Если вы удалите вызов 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;

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

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

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


ENUM

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 самостоятельно, поскольку этот материал выполняется компилятором при создании перечисления и может привести к ошибке компиляции, если вы попытаетесь сделать это самостоятельно.

Другие вопросы по тегам