目录
什么是枚举
枚举就是一个一个的枚举出来,顾名思义就是一个有限的集合。下面是来自百度百科的一句话:
在数学和计算机科学理论中,一个集的枚举是列出某些有穷序列集的所有成员的程序,或者是一种特定类型对象的计数。这两种类型经常(但不总是)重叠。 [1] 是一个被命名的整型常数的集合,枚举在日常生活中很常见,例如表示星期的SUNDAY、MONDAY、TUESDAY、WEDNESDAY、THURSDAY、FRIDAY、SATURDAY就是一个枚举。
出现的原因
在java5之前,我们可以这样来实现枚举
package Java高级特性.枚举;
public class Mj {
public static final int spring = 1;
public static final int summer = 2;
public static final int fall = 3;
public static final int winter = 4;
public static void main(String[] args) {
Mj m = new Mj();
switch (m.spring){
case 1 :
System.out.println("春天");
break;
case 2 :
System.out.println("夏天");
break;
case 3 :
System.out.println("秋天");
break;
case 4 :
System.out.println("冬天");
break;
default:
System.out.println("地球没有的季节");
}
}
}
但是因为我们使用的是int枚举模式,通常我们写代码都会考虑到代码的安全性、易用性、可读性,我们可以发现上面的代码存在着安全性的问题,我们无法保证传入的int类型的值都一定合法。其次,从代码的可读性考虑,我们其实真正需要的是变量的名字,而不是变量里面所存储的值,那有的人会说,那我们可以使用字符串啊,但是字符串是基于比较操作的,又会带来性能上的问题。因此,综合安全性、可读性、效率方面,java5提出来一种枚举类型,可以避免int枚举类型和String枚举类型的缺点,并提供了许多额外的好处。
枚举定义
枚举是一个被命名的整形常数的集合,用于声明一组带标识符的常数。比如一年的四季,一周的七天,方向的东西南北等等。当一个变量有几种固定可能的取值时,我们将它定义为枚举类型。
格式
修饰符 enum 名字{
枚举成员
}
- 任意两个枚举成员不能有相同的名字,且它的常数值必须在相应基础数据类型的范围内,多个枚举成员之间用,隔开。
本质
这是一个自定义枚举类的源代码:
package Java高级特性.枚举;
public enum Season {
spring, summer, fall, winter;
}
经过反编译之后(在命令行窗口,用javac编译名字.java文件生成.class文件,之后用javap反编译该.class文件就可以得到反编译的结果了),下面是反编译之后的结果:
Compiled from "111.java"
final class Season extends java.lang.Enum<Season> {
public static final Season spring;
public static final Season summer;
public static final Season fall;
public static final Season winter;
public static Season[] values();
public static Season valueOf(java.lang.String);
static {};
}
从反编译结果我们可以看出,枚举本质上是一种特殊的类,默认继承了Enum,且里面定义了本身的静态类,这几个静态类的名字分别为我们的枚举成员的名字,相信通过反编译之后的结果我们可以对枚举类有一个更清晰的认识。
补充
- java的枚举类使用关键字enum,和class,interface地位等同。
- java的枚举类默认继承了java.lang.Enum类,因为java中继承是单继承,所以枚举类不可以继承其他类,又因为从反编译结果我们可以看出枚举类被final修饰,所以也不能被其他类继承。但是枚举类可以实现接口。
- 枚举成员默认使用public static final修饰(不显式声明),构造方法默认使用private修饰(,不显式声明,也只能用private修饰)
- 枚举成员必须在第一行列出,不用添加修饰符,系统会默认添加
- 枚举类可以实现一个或多个接口,实现接口时同样要重写所有方法
- 枚举类里面可以定义新的变量(注意:变量和枚举成员是不一样的)和方法
使用
在switch中的使用
在java中,switch中的类型只能是byte,short,int,char,String,枚举类型
package Java高级特性.枚举;
public enum Season {
spring, summer, fall, winter;
Season(){}
public static void main(String[] args) {
//枚举类是特殊的类,每个枚举成员相当于在类里面定义的类型为本类的静态类
//可以使用.成员变量名字赋值
Season s = Season.spring;
switch (s){
case spring:
System.out.println("春天");
break;
case summer:
System.out.println("夏天");
break;
case fall:
System.out.println("秋天");
break;
case winter:
System.out.println("冬天");
break;
}
}
}
/*
输出结果:
春天
*/
枚举类构造方法的使用
可以把枚举类看成普通的类,只不过里面定义了几个类型为本类的静态类(枚举成员)。
package Java高级特性.枚举;
public enum Season {
spring("春天"), summer("夏天"), fall("秋天"), winter("冬天");
private String name;
Season(){}
Season(String name){
this.name = name;
}
public static void main(String[] args) {
Season s = Season.spring;
switch (s){
case spring:
System.out.println(s.name);
break;
case summer:
System.out.println(s.name);
break;
case fall:
System.out.println(s.name);
break;
case winter:
System.out.println(s.name);
break;
}
}
}
枚举类成员方法使用
其实只要了解了枚举类的本质,我们会发现它其实就是普通的类,了解了之后我们会发现掌握枚举类的基本使用其实也不是很难。
package Java高级特性.枚举;
enum Operator {
add, sub, mul, div;
private int code;
public int getCode(){
return code;
}
public void setCode(int code){
this.code = code;
}
public static void main(String[] args) {
Operator o = Operator.add;
o.setCode(10);
System.out.println(o.getCode());
}
}
枚举类实现接口
通过枚举类实现加、减、乘、除四种操作
package Java高级特性.枚举;
enum Operator {
add{
@Override
public double calculate(double a, double b){
return a + b;
}
},
sub{
@Override
public double calculate(double a, double b){
return a - b;
}
},
mul{
@Override
public double calculate(double a, double b){
return a * b;
}
},
div{
@Override
public double calculate(double a, double b){
return a / b;
}
};
public abstract double calculate(double a, double b);
public static void main(String[] args) {
System.out.println(Operator.add.calculate(10, 20));
System.out.println(Operator.sub.calculate(10, 20));
System.out.println(Operator.mul.calculate(10, 20));
System.out.println(Operator.div.calculate(10, 20));
}
}
/*
输出结果:
30.0
-10.0
200.0
0.5
*/
枚举类的方法
方法 | 说明 |
---|---|
values() | 静态方法,将枚举类中的所有枚举成员以数组的形式返回,返回类型为枚举类的名称 |
valueOf(String name) | 静态方法,传入一个String类型的字符串,返回枚举类中名字等于该字符串的枚举成员 |
ordinal() | 成员方法,返回该枚举成员在枚举类中的位置(索引),从0开始数 |
compareTo() | 成员方法,比较两个枚举成员的索引位置 |
values()
静态方法,将枚举类中的所有枚举成员以数组形式返回,返回类型为枚举类的名称
package Java高级特性.枚举;
public enum Season {
spring("春天"), summer("夏天"), fall("秋天"), winter("冬天");
private String name;
Season(){}
Season(String name){
this.name = name;
}
public static void main(String[] args) throws Exception{
Season[] s = Season.values();
for (Season season : s) {
System.out.println(season);
}
}
}
/*
输出结果:
spring
summer
fall
winter
*/
valueOf(String name)
静态方法,返回在枚举类中名字等于传入字符串的枚举成员
package Java高级特性.枚举;
public enum Season {
spring("春天"), summer("夏天"), fall("秋天"), winter("冬天");
private String name;
Season(){}
Season(String name){
this.name = name;
}
public static void main(String[] args) throws Exception{
Season s = Season.valueOf("spring");
System.out.println(s.name);
}
}
/*
输出结果:
春天
*/
ordinal()
成员方法,将该枚举成员在枚举类中的位置返回(从0开始)。
package Java高级特性.枚举;
public enum Season {
spring("春天"), summer("夏天"), fall("秋天"), winter("冬天");
private String name;
Season(){}
Season(String name){
this.name = name;
}
public static void main(String[] args) throws Exception{
Season[] s = Season.values();
for (Season season : s) {
System.out.println(season.ordinal());
}
}
}
/*
输出结果:
0
1
2
3
*/
compareTo(枚举成员类型 枚举成员)
成员方法,比较不同的枚举成员在枚举类中的位置
package Java高级特性.枚举;
public enum Season {
spring("春天"), summer("夏天"), fall("秋天"), winter("冬天");
private String name;
Season(){}
Season(String name){
this.name = name;
}
public static void main(String[] args) throws Exception{
Season[] s = Season.values();
System.out.println(s[0].compareTo(s[1]));
System.out.println(s[0].compareTo(s[2]));
System.out.println(s[3].compareTo(s[0]));
System.out.println(s[3].compareTo(s[1]));
}
}
/*
输出结果:
-1
-2
3
2
*/
小结
枚举类的优点:
- 枚举类更安全,更简单
- 枚举类具有内置方法
枚举类的缺点:
- 不可以继承其他方法
- 不可以被其他类继承
补充:枚举类不能通过反射获取实例
文章学习与:
https://blog.csdn.net/weixin_51367845/article/details/122020048
https://juejin.cn/post/6844904063935463437#heading-3
https://www.runoob.com/java/java-enum.html