定义
枚举类型(enum type)是指由一组固定的常量组成合法的类型。Java 中由关键字enum来定义一个枚举类型。
Java 枚举类型的定义
public enum Season {
SPRING, SUMMER, AUTUMN, WINER
}
上面的代码说明创建了
Season枚举类型,并声明了四个枚举值,分别是SPRING, SUMMER, AUTUMN, WINER,实际上这段代码是调用了4次Enum(String name, int ordinal),也就是:
SPRING = new Enum("SPRING",0);
SUMMER = new Enum("SUMMER",0);
AUTUMN = new Enum("AUTUMN",0);
WINER = new Enum("WINER",0);
枚举类型特点
不可以在enum 类型中指定枚举项的初始值,如果需要指定枚举项的初始值则重写枚举类型的构造函数。- 枚举类型不支持 public 和 protected 修饰符的构造方法,因此构造函数一定要是 private 或 friendly 的。
enum 类型可以定义新的变量。enum 类型可以定义新的方法。enum 类型可以实现一个或多个接口。- 定义
enum类型时候,如果是简单类型,那么最后一个枚举值后不用跟任何一个符号;但如果有定制方法,那么最后一个枚举值与后面代码要用分号';'隔开,不能用逗号或空格。 - 可以定义根据具体枚举值而相异的类。
- 由于 enum 类型的值实际上是通过运行期构造出对象来表示的。这是因为在使用关键字enum创建枚举类型并编译后,编译器会为我们生成一个相关的类,这个类继承了Java API中的java.lang.Enum类,也就是说通过关键字enum创建枚举类型在编译后事实上也是一个类类型而且该类继承自java.lang.Enum类。
反编译Season.class
final class Season extends Enum
{
//编译器为我们添加的静态的values()方法
public static Season[] values()
{
return (Season[])$VALUES.clone();
}
//编译器为我们添加的静态的valueOf()方法,注意间接调用了Enum也类的valueOf方法
public static Season valueOf(String s)
{
return (Season)Enum.valueOf(com/zeroXuan/enumdemo/Season, s);
}
//私有构造函数
private Season(String s, int i)
{
super(s, i);
}
//前面定义的4种枚举实例
public static final Season SPRING;
public static final Season SUMMER;
public static final Season AUTUMN;
public static final Season WINER;
private static final Season $VALUES[];
static
{
//实例化枚举实例
SPRING = new Season("SPRING", 0);
SUMMER = new Season("SUMMER", 1);
AUTUMN = new Season("AUTUMN", 2);
WINER = new Season("WINER", 3);
$VALUES = (new Season[] {
SPRING, SUMMER, AUTUMN, WINER
});
}
}
用法
用法一:常量
public enum Color {
RED, GREEN, BLANK, YELLOW
}
用法二:switch
num Signal {
GREEN, YELLOW, RED
}
public class TrafficLight {
Signal color = Signal.RED;
public void change() {
switch (color) {
case RED:
color = Signal.GREEN;
break;
case YELLOW:
color = Signal.RED;
break;
case GREEN:
color = Signal.YELLOW;
break;
}
}
}
用法三:向枚举中添加新方法
public enum Color {
RED("红色", 1), GREEN("绿色", 2), BLANK("白色", 3), YELLO("黄色", 4);
// 成员变量
private String name;
private int index;
// 构造方法
private Color(String name, int index) {
this.name = name;
this.index = index;
}
// 普通方法
public static String getName(int index) {
for (Color c : Color.values()) {
if (c.getIndex() == index) {
return c.name;
}
}
return null;
}
// get set 方法
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;
}
}
用法四:覆盖枚举的方法
public enum Color {
RED("红色", 1), GREEN("绿色", 2), BLANK("白色", 3), YELLO("黄色", 4);
// 成员变量
private String name;
private int index;
// 构造方法
private Color(String name, int index) {
this.name = name;
this.index = index;
}
//覆盖方法
@Override
public String toString() {
return this.index+"_"+this.name;
}
}
用法五:实现接口
ublic interface Behaviour {
void print();
String getInfo();
}
public enum Color implements Behaviour{
RED("红色", 1), GREEN("绿色", 2), BLANK("白色", 3), YELLO("黄色", 4);
// 成员变量
private String name;
private int index;
// 构造方法
private Color(String name, int index) {
this.name = name;
this.index = index;
}
//接口方法
@Override
public String getInfo() {
return this.name;
}
//接口方法
@Override
public void print() {
System.out.println(this.index+":"+this.name);
}
}
用法六: 使用接口组织枚举
public interface Food {
enum Coffee implements Food{
BLACK_COFFEE,DECAF_COFFEE,LATTE,CAPPUCCINO
}
enum Dessert implements Food{
FRUIT, CAKE, GELATO
}
}
用法七:单例模式的枚举类型实现
/**
* Created by wuzejian on 2017/5/9.
* 枚举单例
*/
public enum SingletonEnum {
INSTANCE;
private String name;
public String getName(){
return name;
}
public void setName(String name){
this.name = name;
}
}
用法八:enum类中定义抽象方法
> 通过这种方式就可以轻而易举地定义每个枚举实例的不同行为方式。我们可能注意到,enum类的实例似乎表现出了多态的特性,可惜的是枚举类型的实例终究不能作为类型传递使用。
public enum EnumDemo3 {
FIRST{
@Override
public String getInfo() {
return "FIRST TIME";
}
},
SECOND{
@Override
public String getInfo() {
return "SECOND TIME";
}
}
;
/**
* 定义抽象方法
* @return
*/
public abstract String getInfo();
//测试
public static void main(String[] args){
System.out.println("F:"+EnumDemo3.FIRST.getInfo());
System.out.println("S:"+EnumDemo3.SECOND.getInfo());
/**
输出结果:
F:FIRST TIME
S:SECOND TIME
*/
}
}
在enum 类型中使用接口还是抽象方法
- 如果一个方法,每个枚举常量的方法实现都是一样的,那么最好使用接口,,只要在枚举中实现一个接口方法即可。
- 如果每个常量的行为各异,变化大,那么使用抽象方法来做,较为合适。使用抽象方法,每个枚举中的常量都需要实现一遍抽象方法。