目录
枚举的定义
- 一个类中对象数量确定且有限
- 当需要定义一组常量的时候,引入枚举类
- 如果枚举类中只有一个对象则可以作为单例模式的实现
要想真正理解好Enum类,弄清JDK5.0之前枚举的实现是很有必要的
JDK5.0之前只能自定义枚举类
必要部分
- 自定义枚举类用class DIYenum{ }
- private final 属性 链接:为什么使用final,final修饰符解释
- private 构造器 :不允许外界创造对象,只允许使用
- public static final 返回对象的方法
- 其他方法:如get toString
例子:自定义一个类DIYenum,用于一年四个季节枚举对象的存放
class DIYenum{//自定义枚举类,用class
//属性、构造器、其他方法、返回对象方法
//1,确定不变的属性
private final String name;
private final String describe;
//final属性必须初始化,可以直接初始化也可以在构造器中初始化
//2,私有构造器
private DIYenum(String name,String describe){
this.name=name;
this.describe=describe;
}
//3,返回对象的方法,外界由此获取枚举成员,因此必须为public static
public static final DIYenum SPRING = new DIYenum("春天","春意盎然");
public static final DIYenum SUMMER = new DIYenum("夏天","酷暑难耐");
public static final DIYenum AUTUMN = new DIYenum("秋天","秋风萧瑟");
public static final DIYenum WINTER = new DIYenum("冬天","寒冬腊月");
//4,其他方法
//可以有get方法,但不能有set方法
public String getName() {
return name;
}
public String getDescribe() {
return describe;
}
//toString方法
@Override
public String toString() {
return "DIYenum{" +
"name='" + name + '\'' +
", describe='" + describe + '\'' +
'}';
}
}
然后运行如下代码
DIYenum season1 = DIYenum.AUTUMN;
DIYenum season2 = DIYenum.SPRING;
DIYenum season3 = DIYenum.WINTER;
DIYenum season4 = DIYenum.SUMMER;
System.out.println(season1);
System.out.println(season2);
System.out.println(season3);
System.out.println(season4);
自定义枚举类的理解:
为了保证枚举类的不变性:将属性设置为私有
为了保证枚举类的确定性:将属性设置为final
为了保证枚举类的私有性:将构造设置为私有
为了保证枚举类的有限性:在类内部new完所有枚举对象
为了保证枚举类可以调用:提供static方法返回上述new的对象
JDK5.0之后enum关键字定义枚举类
区别于自定义枚举类
- 不用class定义类,而用enum定义类
- 用enum(小写)定义的枚举类默认继承于java.lang.Enum(大写)类
- enum类引入的目的是简化结构,重复内容的省略
- 枚举对象的创建需放在enum类的开头,并且省略自定义枚举类中重复的内容public static final
- 属性定义的private final作为重复内容也可以省略
- 构造器、属性作为区分枚举类的结构不能省略
public class UsingEnum {
public static void main(String[] args) {
Season season1 = Season.SPRING;
System.out.println(season1);
}
}
enum Season{
//省略public static final Season XXXXXX = new Season(xxx);
//即下面4个本质上是静态方法,返回一个枚举对象
SPRING("春天","春意盎然"),
SUMMER("夏天","酷暑难耐"),
AUTUMN("秋天","秋风萧瑟"),//不同枚举对象之间用逗号隔开
WINTER("冬天","寒冬腊月");//最后一个用分号截断
//省略private final
String name;
String describe;
//私有构造器不变
private Season(String name,String describe){
this.name = name;
this.describe = describe;
}
//重写toString方法
@Override
public String toString() {
return "Season{" +
"name='" + name + '\'' +
", describe='" + describe + '\'' +
'}';
}
}
enum的父类Enum的常用方法
enum继承于Enum,故用enum定义的枚举类型可以使用Enum类中的一切方法,API文档如下
toString方法和valueOf方法
- enum类本身默认重写了toString方法,例如:Season.SPRING.toString()返回的是字符串"SPRING";
- 相应的,enum中的valueOf方法则是把字符串转化为枚举常量对象,例如:valueOf("SPRING")将返回一个SPRING对象
- toString和valueOf是两个方向相反的方法
- 因此在重写toString方法的时候最好顺便把valueOf方法也相对应的重写了
valueOf方法
默认的valueOf方法的( )中必须输入跟罗列出来的枚举常量名一模一样的字符串才能转换,否则报错IllegalArgumentException
例1:默认的valueOf方法,括号内“春天”跟原enum Season中定义的常量名一样
System.out.println(Season.valueOf("春天"));
//输出“春天”对应的toString方法
例2:重写valueOf方法,可以通过重写来达到模糊查找的效果
public static Season valueOf(String S ,String name) throws Exception {
if(Season.SPRING.name==name||name=="春"||name=="春季"){
return SPRING;
} if(Season.SUMMER.name==name||name=="夏"||name=="夏季"){
return SUMMER;
} if(Season.AUTUMN.name==name||name=="秋"||name=="秋季"){
return AUTUMN;
} if(Season.WINTER.name==name||name=="冬"||name=="冬季"){
return WINTER;
}
else{
throw new Exception();
}
}
System.out.println(Season.valueOf("","春天").toString());
System.out.println(Season.valueOf("","春").toString());
System.out.println(Season.valueOf("","春季").toString());
values方法
values()是一个静态方法,返回一个数组,该数组是该enum类的所有常量构成的
Season[] arr = Season.values();
for(Season s:arr){//foreach循环
System.out.println(s);
}
链接:foreach循环介绍
ordinal方法
该方法返回目标常量对应的序号
枚举常量的序号从0开始排,依次加1
Season[] arr = Season.values();
for(Season s:arr){
System.out.println(s.ordinal());
}
结果:
comparaTo方法
该方法是 调用者-形参 对应的序号结果
System.out.println(Season.SPRING.compareTo(Season.AUTUMN));
结果为:-2
表示SPRING的序号减去AUTUMN的序号=-2
enum枚举类实现接口
写一个接口SeasonShow,定义一个抽象方法show
interface SeasonShow{
public abstract void show();
}
让枚举类Season实现接口SeasonShow并重写抽象方法
抽象方法的逐个重写
抽象方法的重写一般需要在不同的枚举常量重写不同的情况,因此在定义这些枚举常量后面用代码块包裹重写的方法
enum Season implements SeasonShow{
SPRING("春天","春意盎然"){
@Override
public void show(){
System.out.println("春天的时候,光秃秃的树枝上,树叶早已视而不见,此时新芽悄然冒出,像一个刚钻出蛋壳的小鸡一 样,露出白嫩的毛茸茸的绿芽儿,不由的让人怜惜。");
}
},
SUMMER("夏天","酷暑难耐"){
public void show(){
System.out.println("夏天的时候,太阳似火球一般,炙烤着大地,空气闷热,地面滚烫滚烫。路旁的树木无精打采地站立在那,没有一丝风,树叶纹丝不 动,上面落满了厚厚的灰。");
}
},
AUTUMN("秋天","秋风萧瑟"){
public void show(){
System.out.println("秋天的时候,秋庄稼的叶片全然脱略了金子的那层讨厌的贼亮,把育苗到结实的辛勤的全过程积淀成一种沉着的,富于质感的,略带干涩的黄。人们正在辛勤 着收割着自己的劳动果实。");
}
},
WINTER("冬天","寒冬腊月"){
public void show(){
System.out.println("冬天的时候,整个外面全是白茫 茫的一片,屋上,树上,平时走过的小路,一切都在一夜间变的如此的多采。冬天是庄严的,静穆的,使每个人去沉思,而不再轻浮。");
}
};
String name;
String describe;
//省略构造器、各种方法等
}
运行
Season[] arr = Season.values();
for(Season s:arr){
s.show();
}
结果