我们可以为枚举类添加构造器、方法和字段,如下所示:
enum Size {
SMALL("S"), MEDIUM("M"), LARGE("L"), EXTRA_LARGE("XL");
private String abbreviation;
private Size(String abbreviation) {
this.abbreviation = abbreviation;
}
public String getAbbreviation() {
return abbreviation;
}
public static void main(String[] args) {}
}
其中,SMALL、MEDIUM、LARGE、EXTRA_LARGE 是 Size 类的四个实例,这些实例的定义必须先于方法和字段。并且,Size 类有且仅有这四个实例,因为枚举类的构造器总是私有的
,不能再构造其他实例。
补充:由于枚举类不可能构造新的对象,在比较两个枚举类型的值时可以直接使用==
判断。
所有的枚举类型都是Enum
类的子类,我们将上述代码编译后,进行反编译看看:
final class com.company.Size extends java.lang.Enum<com.company.Size> {
public static final com.company.Size SMALL;
public static final com.company.Size MEDIUM;
public static final com.company.Size LARGE;
public static final com.company.Size EXTRA_LARGE;
private java.lang.String abbreviation;
private static final com.company.Size[] $VALUES;
public static com.company.Size[] values();
public static com.company.Size valueOf(java.lang.String);
private com.company.Size(java.lang.String);
public java.lang.String getAbbreviation();
public static void main(java.lang.String[]);
private static com.company.Size[] $values();
static {};
}
我们可以看到,编译器生成的 Size 类是由final
修饰的,并且继承自 Enum 类。其中的实例字段都被声明为公有的静态常量,这些字段应该是在静态初始化块中完成初始化的。
仔细看一下上述结果,我们还可以发现多出了两个方法:values
和valueOf
方法,这两个方法都是由编译器添加的。
我们简单演示一下比较常用的方法:
public class Main {
public static void main(String[] args) {
String str = Size.SMALL.toString(); // 返回枚举常量名
Size size = Enum.valueOf(Size.class, str); // 常量名转枚举常量
Size[] values = Size.values(); // 返回一个包含全部枚举常量的数组
for(Size v : values) {
// 返回枚举常量在类中声明的位置(从零开始)
System.out.println(v.ordinal());
}
}
}
补充:有一个与 values 方法类似的方法,即Class
类中的getEnumConstants
方法·。
public class Main {
public static void main(String[] args) {
Size s = Size.SMALL;
Size[] enumConstants = s.getClass().getEnumConstants();
System.out.println(Arrays.toString(enumConstants));
}
}
如枚举类中包含抽象方法,或者枚举类实现了某个接口,但没有覆盖其中的抽象方法,这个枚举类将被声明为抽象的。这时,我们必须以内部类的形式对枚举类中的实例完成初始化。
interface demo {
void foo();
}
enum Size implements demo{
SMALL("S"){
@Override
public void foo() {
System.out.println("SMALL");
}
}, MEDIUM("M"){
@Override
public void foo() {
System.out.println("MEDIUM");
}
};
private String abbreviation;
private Size(String abbreviation) {
this.abbreviation = abbreviation;
}
public String getAbbreviation() {
return abbreviation;
}
public static void main(String[] args) {
}
}
我们反编译看看:
abstract class com.company.Size extends java.lang.Enum<com.company.Size> implements com.company.demo {
public static final com.company.Size SMALL;
public static final com.company.Size MEDIUM;
private java.lang.String abbreviation;
private static final com.company.Size[] $VALUES;
public static com.company.Size[] values();
public static com.company.Size valueOf(java.lang.String);
private com.company.Size(java.lang.String);
public java.lang.String getAbbreviation();
public static void main(java.lang.String[]);
private static com.company.Size[] $values();
static {};
}
枚举类被声明为抽象类!看下文件夹中的文件!
确实有两个内部类。
如有错误,欢迎指正。.... .- ...- . .- -. .. -.-. . -.. .- -.-- -.-.--