前言
今天我们聊一聊Java枚举
一、什么是枚举
顾名思义,一个一个地列举出来枚举是一种特殊的类,包含一组**有限**的**确定**数量的集合
例如:春夏秋冬,周一到周日,男女,这些都是有限,固定的
二、为什么有枚举
个人认为也是一种规范吧,如果没有枚举,我定义春夏秋冬为常量1、2、3、4,我定义周一到周日为1、2、3、4、5、6、7;此时,如果我单独说一个1,你不知道我说的是春天还是周一,所以可读性很差,而且也令人感觉不规范。 而且我判定“春天”的时候,可以用之前定义的常量名,也可以用1,这也感觉不是很规范。 综上,不用枚举也可以做一些事情,但是感觉不优雅。 但是,如果接口使用枚举的话,得保证双方都有这个sdk,并且版本是一致的。三、如何实现枚举
1.自定义枚举类
主要注意4点:
- 属性私有化
- 构造方法私有化
- new出所有的对象,并且用public static final修饰
- 对相应的属性提供get方法
以季节为例,代码如下:
package org.example.enumstudy;
public class Seasons01 {
// 1.提供私有的属性
private String name;
private String desc;
// 2.构造方法私有化
private Seasons01(String name, String desc) {
this.name = name;
this.desc = desc;
}
// 3.固定对象个数,需要几个对象先new出来,且不能修改,public static final修饰保证外界可直接访问且不能修改
public static final Seasons01 SPRING = new Seasons01("春天","万物复苏");
public static final Seasons01 SUMMER = new Seasons01("夏天","鸟语蝉鸣");
public static final Seasons01 AUTUMN = new Seasons01("秋天","五谷丰登");
public static final Seasons01 WINTER = new Seasons01("冬天","白雪皑皑");
// 4.相应的get方法,不需要set方法
public String getName() {
return name;
}
public String getDesc() {
return desc;
}
}
2.使用enum关键字实现枚举
与第一种实现的区别:
- 使用enum关键字修饰
- 枚举对象必须放在枚举类的首行,不用写修饰符,多个枚举对象之间用逗号分隔,最后一个枚举对象用分号结尾
- 如果调用无参构造器,这里可以只写一个名称
代码如下:
package org.example.enumstudy;
// 采用enum关键字,反编译会发现被enum修饰的类会被final修饰,并且继承java.lang.Enum类
// 枚举对象会自动被public static final 修饰
public enum Seasons02 {
// 枚举对象必须放在首行,如果有多个对象,用逗号分割,最后一个对象用";"结尾
OTHER, // 如果有无参构造器,这里可以只写一个名称,省去小括号
SPRING ("春天","万物复苏"),
SUMMER ("夏天","鸟语蝉鸣"),
AUTUMN ("秋天","五谷丰登"),
WINTER ("冬天","白雪皑皑");
private String seasonName;
private String desc;
// 构造方法,不写修饰符默认是private的
Seasons02(String name, String desc) {
this.seasonName = name;
this.desc = desc;
}
// 为了测试,提供一个无参构造
Seasons02() {}
// get方法
public String getName() {
return seasonName;
}
public String getDesc() {
return desc;
}
}
顺便提一句,如果这里用javap反编译看class文件会发现源码是这样的:
// 当然,我也不是很懂,就是粘出来玩玩
public final class org.example.enumstudy.Seasons02 extends java.lang.Enum<org.example.enumstudy.Seasons02> {
public static final org.example.enumstudy.Seasons02 OTHER;
public static final org.example.enumstudy.Seasons02 SPRING;
public static final org.example.enumstudy.Seasons02 SUMMER;
public static final org.example.enumstudy.Seasons02 AUTUMN;
public static final org.example.enumstudy.Seasons02 WINTER;
public static org.example.enumstudy.Seasons02[] values();
public static org.example.enumstudy.Seasons02 valueOf(java.lang.String);
public java.lang.String getName();
public java.lang.String getDesc();
static {};
}
四、枚举类中的常用方法
其实,一般情况下,我们是用enum关键字来实现枚举的
代码如下:
package org.example.enumstudy;
public class Test {
public static void main(String[] args) {
// 常用方法
// 1.values() 返回该枚举类型中的所有对象
Seasons02[] seasons = Seasons02.values();
for (Seasons02 season : seasons) {
System.out.println("season.getName()=" + season.getName());
}
System.out.println("=====================================================");
// 2.valueOf(String name) 返回该名称(定义时候起的那个名字)的枚举对象
Seasons02 autumn = Seasons02.valueOf("AUTUMN");
System.out.println("autumn.getDesc()=" + autumn.getDesc());
System.out.println("=====================================================");
// 3.name() 和 toString() 返回当前枚举对象的常量名,name方法有final修饰,不能被重写
String name = autumn.name();
String toString = autumn.toString();
System.out.println("name=" + name + " toString=" + toString);
System.out.println("=====================================================");
// 4.ordinal() 返回当前对象的位置号(默认从0开始)
Seasons02 summer = Seasons02.SUMMER;
System.out.println("summer.ordinal()=" + summer.ordinal());
System.out.println("=====================================================");
// 5.compareTo() 比较两个枚举类型是不是同一个对象(实际比较的是这个编号)
// 返回前面对象的编号减去后面对象的编号的int值,如果相等,则值为零
System.out.println("summer.compareTo(Seasons02.SUMMER)=" + summer.compareTo(Seasons02.SUMMER));
System.out.println("summer.compareTo(Seasons02.AUTUMN)=" + summer.compareTo(Seasons02.AUTUMN));
}
}
控制台打印:
season.getName()=null
season.getName()=春天
season.getName()=夏天
season.getName()=秋天
season.getName()=冬天
=====================================================
autumn.getDesc()=五谷丰登
=====================================================
name=AUTUMN toString=AUTUMN
=====================================================
summer.ordinal()=2
=====================================================
summer.compareTo(Seasons02.SUMMER)=0
summer.compareTo(Seasons02.AUTUMN)=-1
五、其它注意
使用enum关键字修饰的枚举类也是一个类,通过反编译可以看到它是继承了Enum类的。和普通类一样,它就不能再继承其它类,但是它可以实现其它接口。总结
本文对枚举进行了入门级别的阐述,当然,如果刨根问底,还有很多东西可以探究,由于水平有限,暂不深究。
由于才疏学浅,难免疏漏,若有高见,欢迎指点,不甚感激!