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

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

Ответ 1

Функционально, да. Буквально нет (вы не можете явно подкласса Enum с одной стороны). enum(s) имеют a 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;
    }
}

Ответ 2

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

Скомпилированное перечисление будет содержать флаг 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

CLASS

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

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

Ответ 3

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