枚举类
枚举(enum
)类型是Java 5新增的特性,它是一种新的类型,允许用常量来表示特定的数据片段,而且全部都以类型安全的形式来表示。
所有的枚举都继承自java.lang.Enum
类,又由于Java不支持多继承,所以枚举对象不能再继承其他类(但是可以实现interface
)。
enum
可以让编译器自动检查某个值是否在枚举的集合里,并且,不同用途的枚举需要不同的类型来标记,不能混用,我们可以使用enum
来定义枚举类:
public class Main {
public static void main(String[] args) {
Weekday day = Weekday.SUN;
if (day == Weekday.SAT || day == Weekday.SUN) {
System.out.println("Work at home!");
}
else {
System.out.println("Work at office!");
}
}
}
enum Weekday {
SUN, MON, TUE, WED, THU, FRI, SAT;
}
使用enum
定义枚举有以下好处:
enum
常量本身就带有类型信息,即Weekend.SUM
类型是Weekend
,编译器会自动检查出类型错误。例如:
int day = 1;
if(day == Weekend.SUN){
//java: 不兼容的类型: Weekday无法转换为int
}
- 不可能引用到非枚举的值,因为无法通过编译。
Weekday day = Weekday.SUN;
if(day=Weekday.AAA){
}
- 不同类型的枚举不能相互比较或者赋值,因为类型不符。例如,不能给一个
Weekend
枚举类型的变量赋值为Color
枚举类型的值:
Weekday a = Weekday.SUN;
Weekday b = Color.RED; //java: 不兼容的类型: Color无法转换为Weekday
enum的比较
使用enum
定义的枚举类是一种引用类型。前面说过,引用类型的比较,要使用equals()
方法,如果使用==
比较,它比较的是两个引用类型的变量是否是同一个对象。因此,引用类型比较,要始终使用equals()
方法,但是enum
类型可以例外。
这是因为enum
类型的每个常量在JVM中只有一个唯一实例,所以可以直接使用==
比较:
if(day == Weekend.FRI){ // 可以
}
if(day.equals(Weekend.SUN)) //可以,但是代码更多
enum的类型
通过enum
定义的枚举类。和其他class
有什么区别?
答案是没有任何区别。enum
定义的类型就是class
,只不过它有以下几个特点:
- 定义的
enum
类型总是继承自java.lang.Enum
,且无法被继承,但可以实现接口; - 只能定义出
enum
的实例,而无法通过new
操作符创建enum
的实例; - 定义的每个实例都是引用类型的唯一实例;
- 可以将
enum
类型用于switch
;
例如我们定义的Color
枚举类:
public enum Color{
RED,GREEN,BLUE;
}
编译器编译出的class
大概就像这样:
public final class Color extends Enum{
public static final Color RED = new Color();
public static final Color GREEN = new Color();
public static final Color BLUE = new Color();
private Color(){
}
}
所以编译后的enum
类和普通class
没有任何区别。但是我们自己无法按定义普通class
那样来定义enum
,必须使用enum
关键字,这是Java语法规定的。
enum
的一些方法:
name()
返回常量名。例如:
String s = Weekend.SUM.name(); // "SUN"
ordinal()
返回定义的常量的顺序,从0开始计数,例如:
int n = Weekend.MON.ordinal(); // 1
改变枚举常量定义的顺序就会导致ordinal()
返回值发生变化。
values()
遍历所有枚举
public class Main {
public static void main(String[] args) {
for(Color color : Color.values()){
System.out.println(color.name());
}
}
}
enum Color{
RED,GREEN,BLUE;
}
输出:
RED
GREEN
BLUE
- 自定义方法
public class Main {
public static void main(String[] args) {
for(Color color : Color.values()){
System.out.println(color+"名字:"+color.getName()+" 索引:"+color.getIndex());
}
}
}
enum Color{
RED("red",1),GREEN("green",2),BLUE("blue",3);
private String name;
private int index;
Color(String name, int index) {
this.name = name;
this.index = index;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getIndex() {
return index;
}
public void setIndex(int index) {
this.index = index;
}
}
输出:
RED名字:red 索引:1
GREEN名字:green 索引:2
BLUE名字:blue 索引:3
- 实现接口
所有的枚举都继承自java.lang.Enum
类。由于Java不支持多继承,所以枚举对象不能再继承其他类,但是可以实现接口。
enum Color implements OtherColor{
}
- switch
public class Main {
public static void main(String[] args) {
Color color = Color.BLUE;
switch(color){
case BLUE:
System.out.println("BLUE");
break;
case RED:
System.out.println("RED");
break;
default:
System.out.println("GREEN");
}
}
}
enum Color{
RED,BLUE,GREEN;
}
输出:
BLUE