枚举Enum

简介

枚举是Java1.5引入的新特性,通过关键字enum来定义枚举类。枚举类是一种特殊类,它和普通类一样可以使用构造器、定义成员变量和方法,也能实现一个或多个接口,但枚举类不能继承其他类.

枚举常量

 

 

 jad工具来反编译Color类, 通过jad -sjava Color.class反编译出一份java文件

 

 

 

 该类继承自 Enum类,public abstract class Enum<E extends Enum<E>>implements Comparable<E>, Serializable.

 在enum关键字的类中,第一行 (准确的说是第一个分号前) 定义的变量,都会生成一个 Color实例,且它是在静态域中进行初始化的, 而静态域在类加载阶段的cinit中进行初始化,所以枚举对象是线程安全的,由JVM来保证.

Enum类实现了 Comparable接口,表明它是支持排序的,可以通过 Collections.sort 进行自动排序.实现了public final int compareTo(E o)接口,方法定义为final且其实现依赖的ordinal字段也是final类型,说明他只能根据ordinal排序,排序规则不可变.

ordinal: 表示枚举的顺序,从Color类中可以看出,它是从0开始按自然数顺序增长,且其值是final类型,外部无法更改.

每一个枚举类型极其定义的枚举变量在JVM中都是唯一的

这句话的意思是枚举类型它拥有的实例在编写的时候,就已经确定下,不能通过其他手段进行创建,且枚举变量在jvm有且只有一个对应的实例.

为了达到这个效果,它通过以下方法来确保.

  1. 类加载时创建,保证线程安全
  2. 对序列化进行特殊处理,防止反序列化时创建新的对象
  3. 私有构造函数, 无法正常的 new出对象
  4. 无法通过 clone()方法,克隆对象
  5. 无法通过反射的方式创建枚举对象

枚举类型,在 JVM 层面禁止了通过反射构造枚举实例的行为,如果尝试通过反射创建,将会报Cannot reflectively create enum objects.

枚举类的特点总结

枚举实例必须在 enum关键字声明的类中显式的指定(首行开始的以第一个分号结束)

除了1, 没有任何方式(new,clone,反射,序列化)可以手动创建枚举实例

枚举类不可被继承

枚举类是线程安全的

枚举类型是类型安全的(typesafe)(类型转换安全,比如泛型也是一种保护类型安全的措施)

 无法继承其他类(已经默认继承Enum)

枚举的使用

可以在 switch语句中使用

EnumSet和EnumMap

  1. Java 中提供了两个方便操作enum的工具类——EnumSet 和 EnumMap;
  2. EnumSet 是枚举类型的高性能 Set 实现。它要求放入它的枚举常量必须属于同一枚举类型。
  3. EnumMap 是专门为枚举类型量身定做的 Map 实现。虽然使用其它的 Map 实现(如HashMap)也能完成枚举类型实例到值得映射,但是使用 EnumMap 会更加高效:它只能接收同一枚举类型的实例作为键值,并且由于枚举类型实例的数量相对固定并且有限,所以 EnumMap 使用数组来存放与枚举类型对应的值。这使得 EnumMap 的效率非常高。

扩展阅读

https://blog.csdn.net/javazejian/article/details/71333103

 

代码:

 1 package day14;
 2 
 3 public enum Color{
 4     //这个类不能继承别的类
 5     //Java里面是单继承
 6     //这里默认继承自Enum
 7     //所以就不能继承别的类了
 8     
 9     
10     //枚举类首行必须枚举实例
11     //首行是指分号结束
12     RED(1 , "red"){
13         public String rgb() {return "rgb(255,0,0)";}
14     } , BLUE(2 , "blue"){
15         public String rgb() {return "rgb(0,255,0)";}
16     } , YELLOW(3 , "yellow"){
17         public String rgb() {return "rgb(0,0,255)";}
18     };
19     
20     int index;
21     String name;
22     private Color(int index , String name) {
23         this.index = index;
24         this.name = name;
25     }
26     public String rgb() {
27         return null;
28     }
29 
30     public static void main(String[] args) {
31         //ordinal返回的是下标
32         System.out.println(Color.RED.ordinal());//0    不可以修改的
33         System.out.println(Color.RED.name());//RED    不可以修改的
34         Color c = Color.valueOf(Color.class , "RED");
35         switch (c) {
36         case RED:
37             System.out.println("RED");
38             break;
39         case BLUE:
40             System.out.println("BLUE");
41             break;
42         case YELLOW:
43             System.out.println("YELLOW");
44             break;
45         }
46     }
47 }

 

posted @ 2022-02-14 11:51  Nickeyhu  阅读(92)  评论(0编辑  收藏  举报