JDK1.5后的枚举类型

枚举

枚举是在JDK1.5以后引入的。
主要用途:将一组常量组织起来。

这里创建一个名为TestEnum的枚举类型:

public enum TestEnum {
	RED,BLACK,GREEN;
}

优点:将常量组织起来统一进行管理(枚举类型都是常量,一般都用大写字母表示)
应用场景:错误状态码,消息类型,颜色的划分,状态机等
本质:是java.lang.Enum 的子类,也就是说TestEnum默认继承了java.lang.Enum这个类。

1 enum枚举在switch语句中使用
public class Main {
    public enum TestEnum{
        RED,BLACK,GREEN;
    }
    public static void main(String[] args) {
        TestEnum testEnum2 = TestEnum.BLACK;
	System.out.println(testEnum2);
        switch (testEnum2) {
            case RED:
                System.out.println("red");
                break;
            case BLACK:
                System.out.println("black");
                break;
            default:
                break;
        }
    }
}
结果:
BLACK
black
2 Enum 类的常用方法
  • values() 以数组形式返回枚举类型的所有成员(保持在enum中的声明顺序)
  • ordinal() 获取枚举成员的索引位置(索引位置从0开始)
  • valueOf() 将给定的字符串转换为枚举实例,如果不存在将会抛出异常。(TestEnum.valueOf(“GREEN”))
  • compareTo() 比较两个枚举成员在定义时的顺序,Enum类实现了Comparable接口,所以它具有compareTo()方法。
public class Main {
    public enum TestEnum{
        RED,BLACK,GREEN;
    }
    public static void main(String[] args) {
       for(TestEnum x:TestEnum.values()){
           System.out.println(x+"的索引位置为:"+x.ordinal());
           System.out.println(x.compareTo(TestEnum.RED));
           System.out.println(x.getDeclaringClass());
           System.out.println(x.name());
       }
	System.out.println(TestEnum.valueOf("RED"));

    }
}
部分结果:
RED的索引位置为:0
0
class com.Main$TestEnum
RED

BLACK的索引位置为:1
1
class com.Main$TestEnum
BLACK
.
.
.
RED
  • 调用getDeclaringClass()方法就能知道enum实例所属的类
  • name()返回enum声明时的名字。
  • enum中重写了toString()方法,所以可以直接打印枚举实例的名字。
3 枚举——常规类

我们可以将enum看作一个常规的类,除了不能继承它。我们可以向enum中添加方法,enum中也可以有main方法。

注意:
enum中枚举实例的声明必须放在最前面,否则会报错。

在Java当中枚举实际上就是一个类。

public enum TestEnum {
    RED("red",1),BLACK("black",2),WHITE("white",3);
    private String name;
    private int key;
 
    private TestEnum (String name,int key) {
        this.name = name;
        this.key = key;
    }
    public static TestEnum getEnumKey (int key) {
        for (TestEnum t: TestEnum.values()) {
            if(t.key == key) {
                return t;
            }
        }
        return null;
    }
    public static void main(String[] args) {
        System.out.println(getEnumKey(2));
    }
}

在枚举中构造方法限制为私有,在我们访问枚举实例时会执行构造方法,同时每个枚举实例都是static final类型的,也就表明只能被实例化一次。在调用构造方法时,enum中的实例被保证只会被实例化一次.因此我们可以利用枚举实现单例模式。普通类的私有构造方法可以通过反射拿到,而枚举类的私有构造方法并不能用反射拿到,所以使用枚举实现单例也是比较安全的。

参考博客:设计模式

4 下面简单介绍一下为什么反射不能用于枚举类

java.lang.Enum这个类中的构造方法:

   protected Enum(String name, int ordinal) {
        this.name = name;
        this.ordinal = ordinal;
    }

当我们想通过反射拿到枚举类的构造方法时,报错了。

 public static void main(String[] args) {
        try {
            Class<?> c1 = Class.forName("TestEnum");
            Constructor constructor = c1.getDeclaredConstructor(String.class,int.class,String.class,int.class);
            System.out.println(constructor);
            constructor.setAccessible(true);
            TestEnum testEnum =(TestEnum) constructor.newInstance("red",1,"black",2);
            System.out.println(testEnum);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
 结果:
java.lang.IllegalArgumentException: Cannot reflectively create enum objects
	at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:482)
	at reflectdemo.main(reflectdemo.java:12)

我们进入反射源码中发现我们在用newInstance获取枚举类的实例时,有一个if语句,如果是枚举类将会直接抛出异常,也就是说枚举类是不能通过反射获取内部的构造方法的:

public T newInstance(Object ... initargs){
	if ((clazz.getModifiers() & Modifier.ENUM) != 0)
            throw new IllegalArgumentException("Cannot reflectively create enum objects");

注意:
TestEnum testEnum =(TestEnum) constructor.newInstance("red",1,"black",2);这里因为父类中也有有参构造方法,所以我们也需要帮助父类构造方法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值