枚举类:在某些情况下,一个类的对象是有限而且固定的,那么就可以用枚举了。
手动实现枚举类
手动实现枚举类:
- private修饰构造器
- 属性使用privatefinal 修饰
- 把该类的所有实例都使用public static final 来修饰
public class Season {
//1.因为枚举类的对象是有限个,所以不能在类的外部创建类的对象
private Season(String name,String desc){
this.name = name;
this.desc = desc;
}
//2.因为对象是固定的,所以属性是常量
private final String name;
private final String desc;
//3.在类的内部创建对象,但需要在类的外部访问到该对象,而且还不能被修改
public static final Season SPRING = new Season("春天","春风又绿江南岸");
public static final Season SUMMER = new Season("夏天","映日荷花别样");
public static final Season FALL = new Season("秋天","秋水共长天一色");
public static final Season WINTER = new Season("冬天","窗含西岭千秋雪");
public String getName() {
return name;
}
public String getDesc() {
return desc;
}
}
使用enum
public enum Season2 {
//1.必须在枚举类的第一行写出有哪些枚举值
SPRING("春天", "春风又绿江南岸"),
SUMMER("夏天", "映日荷花别样"),
FALL("秋天", "秋水共长天一色"),
WINTER("冬天", "窗含西岭千秋雪");
private final String name;
private final String desc;
private Season2(String name, String desc) {
this.name = name;
this.desc = desc;
}
public String getName() {
return name;
}
public String getDesc() {
return desc;
}
}
enum 对象的常用方法介绍
int compareTo(E o)
比较此枚举与指定对象的顺序。Class<E> getDeclaringClass()
返回与此枚举常量的枚举类型相对应的 Class 对象。String name()
返回此枚举常量的名称,在其枚举声明中对其进行声明。int ordinal()
返回枚举常量的序数(它在枚举声明中的位置,其中初始常量序数为零)。String toString()
返回枚举常量的名称,它包含在声明中。
static <T extends Enum<T>> T valueOf(Class<T> enumType, String name)
返回带指定名称的指定枚举类型的枚举常量。
public enum EnumTest {
MON, TUE, WED{
@Override
public String toString() {
return "Today is Wednesday!";
}
}, THU, FRI, SAT, SUN;
}
//EnumTest
EnumTest test = EnumTest.TUE;
//compareTo(E o)
switch (test.compareTo(EnumTest.MON)) {
case -1:
Log.d("pepe","TUE 在 MON 之前");
break;
case 1:
Log.d("pepe","TUE 在 MON 之后");
break;
default:
Log.d("pepe","TUE 与 MON 在同一位置");
break;
}
//遍历枚举
Log.d("pepe","遍历ColorEnum枚举中的值");
for(EnumTest color : EnumTest.values()){
Log.d("pepe","遍历toString:"+color.toString()+"---ordinal值:"+color.ordinal());
}
//valueOf,由"WED"获取枚举值
EnumTest enumTest=EnumTest.valueOf("WED");
Log.d("pepe","由\"WED\"获取枚举值:"+enumTest.toString());
//values(),获取枚举的个数
Log.d("pepe","ColorEnum枚举中的值有"+EnumTest.values().length+"个");
//getDeclaringClass()
Log.d("pepe","getDeclaringClass(): " + test.getDeclaringClass().getName());
//name() 和 toString()
Log.d("pepe","name(): " + test.name());
Log.d("pepe","toString(): " + test.toString());
//ordinal(), 返回值是从 0 开始
Log.d("pepe","ordinal(): " + test.ordinal());
输出结果:
TUE 在 MON 之后
遍历ColorEnum枚举中的值
遍历toString:MON---ordinal值:0
遍历toString:TUE---ordinal值:1
遍历toString:Today is Wednesday!---ordinal值:2
遍历toString:THU---ordinal值:3
遍历toString:FRI---ordinal值:4
遍历toString:SAT---ordinal值:5
遍历toString:SUN---ordinal值:6
由"WED"获取枚举值:Today is Wednesday!
ColorEnum枚举中的值有7个
getDeclaringClass(): com.zitech.anenum.MainActivity$EnumTest
name(): TUE
toString(): TUE
ordinal(): 1
enum 的方法和接口
覆盖方法
public enum Enumtestt{
MON(1), TUE(2), WED(3), THU(4), FRI(5), SAT(6) {
@Override
public boolean isRest() {
return true;
}
},
SUN(0) {
@Override
public boolean isRest() {
return true;
}
};
private int value;
private Enumtestt(int value) {
this.value = value;
}
public int getValue() {
return value;
}
public boolean isRest() {
return false;
}
}
//Enumtest
Log.d("pepe","Enumtestt.SAT 的 isRest = " + Enumtestt.SAT.isRest());
输出结果:
Enumtestt.SAT 的 isRest = true
实现接口
public enum MyColor implements Behaviour{
RED,GREEN,BLUE;
private final String name="fsd";
// 接口方法
@Override
public String getInfo() {
return this.name;
}
// 接口方法
@Override
public void print() {
Log.d("pepe","name:" + this.name);
}
}
或者
public enum MyColor implements Behaviour{
RED{
@Override
public String getInfo() {
return this.toString();
}
@Override
public void print() {
Log.d("pepe","name:" + this.toString());
}
},GREEN{
@Override
public String getInfo() {
return this.toString();
}
@Override
public void print() {
Log.d("pepe","name:" + this.toString());
}
},BLUE{
@Override
public String getInfo() {
return this.toString();
}
@Override
public void print() {
Log.d("pepe","name:" + this.toString());
}
};
private final String name="fsd";
}
EnumSet,EnumMap 的应用
// EnumSet的使用
EnumSet<EnumTest> weekSet = EnumSet.allOf(EnumTest.class);
for (EnumTest day : weekSet) {
Log.d("pepe",day.toString());
}
// EnumMap的使用
EnumMap<EnumTest, String> weekMap = new EnumMap(EnumTest.class);
weekMap.put(EnumTest.MON, "星期一");
weekMap.put(EnumTest.TUE, "星期二");
// ... ...
for (Iterator<Map.Entry<EnumTest, String>> iter = weekMap.entrySet().iterator(); iter.hasNext();) {
Map.Entry<EnumTest, String> entry = iter.next();
Log.d("pepe",entry.getKey().name() + ":" + entry.getValue());
}
输出结果:
MON
TUE
Today is Wednesday!
THU
FRI
SAT
SUN
MON:星期一
TUE:星期二
原理分析
enum 的语法结构尽管和 class 的语法不一样,但是经过编译器编译之后产生的是一个class文件。该class文件经过反编译可以看到实际上是生成了一个类,该类继承了java.lang.Enum。EnumTest 经过反编译(javap com.hmw.test.EnumTest 命令)之后得到的内容如下:
public class com.hmw.test.EnumTest extends java.lang.Enum{
public static final com.hmw.test.EnumTest MON;
public static final com.hmw.test.EnumTest TUE;
public static final com.hmw.test.EnumTest WED;
public static final com.hmw.test.EnumTest THU;
public static final com.hmw.test.EnumTest FRI;
public static final com.hmw.test.EnumTest SAT;
public static final com.hmw.test.EnumTest SUN;
static {};
public int getValue();
public boolean isRest();
public static com.hmw.test.EnumTest[] values();
public static com.hmw.test.EnumTest valueOf(java.lang.String);
com.hmw.test.EnumTest(java.lang.String, int, int, com.hmw.test.EnumTest);
}
所以,实际上 enum 就是一个 class,只不过 java 编译器帮我们做了语法的解析和编译而已。
项目源码 GitHub求赞,谢谢!