Enum 的全称为 enumeration, 是我们较为常用的类,存放在 java.lang 包中。
public enum EnumTest {
WALK(1, "慢走"),
QUICK(2, "疾步"),
RUN(3, "跑步");
private Integer code;
private String desc;
EnumTest(Integer code, String desc) {
this.code = code;
this.desc = desc;
}
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
}
可以用if/else、switch来遍历
public static EnumTest getByCode(int code) {
for(EnumTest et : EnumTest.values()) {
if (et.getCode().intValue() == code) {
System.out.println(et.getCode() + "_" + et.ordinal());
return et;
}
}
return null;
}
遍历所有定义的value。
ordinal() 方法来得到定义枚举值常量的位置顺序,初始化第一个常量的顺序为0.
enum 的语法结构尽管和 class 的语法不一样,但是经过编译器编译之后产生的是一个class文件。该class文件经过反编译可以看到实际上是生成了一个类,该类继承了java.lang.Enum。
enum 不能使用 extends 关键字继承其他类,因为 enum 已经继承了 java.lang.Enum(java是单一继承)。
但使用枚举,我们需要了解一些注意事项,且可以用枚举来实现怎样的功效?
- 枚举类型带参数,必须要对应匹配的构造方法。
- 可以创建一个enum类,把它看做一个普通的类。除了它不能继承其他类了。
- switch()参数可以使用enum了。
- values()方法是编译器插入到enum定义中的static方法,所以,当你将enum实例向上转型为父类Enum是,values()就不可访问了。解决办法:在Class中有一个getEnumConstants()方法,所以即便Enum接口中没有values()方法,我们仍然可以通过Class对象取得所有的enum实例。
- 无法从enum继承子类,如果需要扩展enum中的元素,在一个接口的内部,创建实现该接口的枚举,以此将元素进行分组。达到将枚举元素进行分组。
- enum允许程序员为eunm实例编写方法。所以可以为每个enum实例赋予各自不同的行为。
- 以职责链(Chain of Responsibility) 的方式来使用枚举,把所有任务定义为枚举值,遍历该枚举依次进行任务处理。
- 使用enum的状态机,然后来动态处理任务。
- 枚举在初始化时,实际会对每个枚举都进行构造实例化。
EnumTest(Integer code, String desc) {
System.out.println(code + "_" + desc);
this.code = code;
this.desc = desc;
}
1_慢走
2_疾步
3_跑步
WALK
我们来进行编译以及反编译,看下具体是怎样的内容:
D:\App\src\main\java\com\test>javac EnumTest.java
D:\App\src\main\java\com\test>javap EnumTest.class
Compiled from "EnumTest.java"
public final class com.test.EnumTest extends java.lang.Enum<com.test.EnumTest> {
public static final com.test.EnumTest WALK;
public static final com.test.EnumTest QUICK;
public static final com.test.EnumTest RUN;
public static com.test.EnumTest[] values();
public static com.test.EnumTest valueOf(java.lang.String);
public static com.test.EnumTest getByCode(int);
public java.lang.Integer getCode();
public void setCode(java.lang.Integer);
static {};
}
枚举类是继承了Enum,所以枚举类不能再继承其他类。定义的枚举值,在编译之后都会生成静态不可变的枚举对象。
最后来个完整的实例:
public class soundModeDemo
{
/**
* 将用enum枚举去除以下方法中的switch/case
*/
public void processAlarmEvents(AlarmEvent[] events)
{
AlarmEvent lastEvent = events[events.length - 1];
byte severity = lastEvent.getAlarmData().getPerceivedSeverity();
switch (lastEvent.getEventType())
{
case AlarmEvent.NEW_ALARM:
if (severity != PerceivedSeverity.SEVERITY_CLEARED)
{
System.out.println("playAlarmSound:"+severity);
}
break;
case AlarmEvent.DELETE_ALARM:
if (severity == PerceivedSeverity.SEVERITY_CLEARED)
{
return;
}
System.out.println("playClearSound:"+severity);
break;
case AlarmEvent.SEVERITY_CHANGED:
byte oldSeverity = lastEvent.getOriginalAlarmData().getPerceivedSeverity();
if ((oldSeverity == PerceivedSeverity.SEVERITY_CLEARED))
{
System.out.println("playAlarmSound:"+severity);
}
else if (severity == PerceivedSeverity.SEVERITY_CLEARED)
{
System.out.println("playClearSound:"+severity);
}
break;
}
}
//带有构造方法的枚举实现
public enum SoundPlay{
NEW_ALARM(AlarmEvent.NEW_ALARM, PerceivedSeverity.SEVERITY_CLEARED, (byte)0),
DELETE_ALARM(AlarmEvent.DELETE_ALARM, PerceivedSeverity.SEVERITY_CLEARED, (byte)0),
SEVERITY_CHANGED(AlarmEvent.SEVERITY_CHANGED, PerceivedSeverity.SEVERITY_CLEARED, (byte)0);
private final byte perceivedSeverity = PerceivedSeverity.SEVERITY_CLEARED;
private byte eventType;
private byte severity;
private byte oldSeverity;
public void setSeverity(byte severity)
{
this.severity = severity;
}
public void setOldSeverity(byte oldSeverity)
{
this.oldSeverity = oldSeverity;
}
Private SoundPlay(byte eventType, byte severity, byte oldSeverity){
this.eventType = eventType;
this.severity = severity;
this.oldSeverity = oldSeverity;
}
public void printAllValues() {
System.out.println("eventType:"+this.eventType+
" severity:"+this.severity+
" oldSeverity:"+this.oldSeverity);
}
public void doPlay(){
if(this.eventType == AlarmEvent.NEW_ALARM)playNewAlarm();
if(this.eventType == AlarmEvent.DELETE_ALARM)playDeleteAlarm();
if(this.eventType == AlarmEvent.SEVERITY_CHANGED)playSeverityChange();
}
private void playSeverityChange()
{
if (this.oldSeverity == perceivedSeverity){
System.out.println("playAlarmSound:" + this.oldSeverity);
}else if (this.severity == perceivedSeverity){
System.out.println("playClearSound:" + this.severity);
}
}
private void playDeleteAlarm()
{
if (this.severity == perceivedSeverity){
return;
}else{
System.out.println("playClearSound:" + this.severity);
}
}
private void playNewAlarm()
{
if (this.severity != perceivedSeverity){
System.out.println("playAlarmSound:" + this.severity);
}
}
}
public static void main(String[] args)
{
//每次调用,都需要设置severity或oldSeverity
SoundPlay soundPlay1 = SoundPlay.NEW_ALARM;
soundPlay1.setSeverity((byte)4);
soundPlay1.printAllValues();
soundPlay1.doPlay();
}
}
//最常用标准的枚举方式
public enum SoundPlay{
NEW_ALARM{
@Override
public void play(AlarmEvent event)
{
if (event.getAlarmData().getPerceivedSeverity() != PerceivedSeverity.SEVERITY_CLEARED){
System.out.println("playAlarmSound:" + event.getAlarmData().getPerceivedSeverity());
}
}
@Override
protected byte getType()
{
return AlarmEvent.NEW_ALARM;
}
},
DELETE_ALARM{
@Override
public void play(AlarmEvent event)
{
if (event.getAlarmData().getPerceivedSeverity() == PerceivedSeverity.SEVERITY_CLEARED){
return;
}else{
System.out.println("playClearSound:" + event.getAlarmData().getPerceivedSeverity());
}
}
@Override
protected byte getType()
{
return AlarmEvent.DELETE_ALARM;
}
},
SEVERITY_CHANGED {
@Override
public void play(AlarmEvent event)
{
if (event.getAlarmData().getPerceivedSeverity() == PerceivedSeverity.SEVERITY_CLEARED){
System.out.println("playAlarmSound:" + event.getOriginalAlarmData().getPerceivedSeverity());
}else if (event.getAlarmData().getPerceivedSeverity() == PerceivedSeverity.SEVERITY_CLEARED){
System.out.println("playClearSound:" + event.getAlarmData().getPerceivedSeverity());
}
}
@Override
protected byte getType()
{
return AlarmEvent.DELETE_ALARM;
}
},
DEFAULT{
@Override
public void play(AlarmEvent event)
{
System.out.println("没有匹配的枚举值内容,调用的默认方法!");
}
@Override
protected byte getType()
{
return -1;
}
};
public abstract void play(AlarmEvent event);
protected abstract byte getType();
public static SoundPlay valueOf(byte eventType){
for(SoundPlay soundPlay:SoundPlay.values()){
if(eventType==soundPlay.getType()){
return soundPlay;
}
}
return DEFAULT;
}
}