您的当前位置:首页正文

java基础之枚举类

2024-11-27 来源:个人技术集锦

什么是枚举

枚举就是一个一个的枚举出来,顾名思义就是一个有限的集合。下面是来自百度百科的一句话:

在数学和计算机科学理论中,一个集的枚举是列出某些有穷序列集的所有成员的程序,或者是一种特定类型对象的计数。这两种类型经常(但不总是)重叠。 [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:///weixin_51367845/article/details/122020048
https://juejin.cn/post/6844904063935463437#heading-3
https://www.runoob.com/java/java-enum.html
显示全文