在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.Enum
的 final
class。但是,请注意,您不能自己直接扩展 java.lang.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;
}
}
我的理解正确吗?
功能上,是的。字面意思是不(一方面你不能明确地 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.Enum
的 final
class。但是,请注意,您不能自己直接扩展 java.lang.Enum
,因为这些东西是由编译器在创建枚举时完成的,如果您尝试自己做,会导致编译错误。