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