今日分享开始啦,请大家多多指教~
今日次要分享的是 Java 枚举,被 enum 关键字润饰的类型就是枚举类型,如果枚举不增加任何办法,枚举值默认为从 0 开始的有序数值。例如:enum Color{RED,GREEN,BLUE};将常量组织起来,对立进行治理。利用的场景为错误码、状态机等;枚举的实质是 java.lang.Enum 的子类。
一、基本概念
枚举是 Java1.5 引入的新个性,通过关键字 enum 来定义枚举类。枚举类是一种非凡类,它和一般类一样能够应用结构器、定义成员变量和办法,也能实现一个或多个接口, 但枚举类不能继承其余类。
二、枚举的优缺点
1、长处
Effctive Java 中之所以举荐用枚举代替所有常量 Code, 起因如下:
(1)类型查看,有效性查看
(2)枚举作为一个类, 能够有本人的属性 (通常应该是常量,我没遇到过不是的状况) 以及本人的办法(否则只能用 switch 来写,理论违反原则)
(3)和常量相比,无需查看文档和源码就能间接晓得所有可能返回值,不便编码。
然而这里的问题就出在第一点上, 实际上分布式环境下(1)并不是必然的。如果业务解决中容许某个接口返回值有未定义内容,那么在反序列化中就不该对此抛出异样, 不用死守(1)。同时, 从第(2)点和第(3)点来看,这样限度枚举的应用范畴造成的影响是极大的。将有本人属性, 本人办法实现的枚举改写为 code 和其余办法的配合,须要的代码量回升不少, 而且代码腐烂度极大减少。
2、毛病
(1)因为 Java 中反对单继承,因而枚举类型不能再继承其余类;
(2)应用枚举作为返回值可能造成的问题其实大家都晓得就是客户端和服务端版本不统一的话, 会造成反序列化异样,于是《阿里巴巴 JAVA 开发手册》对于这个问题的解决方法就采取了尽量避免异样呈现, 所以禁止定义枚举为返回值。
三、解决 ifelse
对于业务开发来说,业务逻辑的简单是必然的,随着业务倒退,需要只会越来越简单,为了思考到各种各样的状况,代码中不可避免的会呈现很多 if-else。
一旦代码中 if-else 过多,就会大大的影响其可读性和可维护性,而且代码显得很 low。
枚举能够解决这个问题;
对于枚举与 switch 是个比较简单的话题,应用 switch 进行条件判断时,条件参数个别只能是整型,字符型。而枚举型的确也被 switch 所反对,在 java 1.7 后 switch 也对字符串进行了反对。这里咱们简略看一下 switch 与枚举类型的应用
四、枚举的罕用办法
1、枚举类
2、枚举类变量中增加属性
3、测试类
public static void main(String[] args) {//1、ordinal(), 枚举程序值
System.out.println("枚举程序值,"+Weekday.MONDAY.ordinal());//1
/*
* 2、valueOf()
* public static <T extends Enum<T>> T valueOf(Class<T> enumType, String name)
* enumType -- 这是枚举类型,返回一个常量的类的对象。* name -- 这是常量,要返回的名称。* return: 此办法返回具备指定名称的枚举类型的枚举常量。* 如果你传了一个不存在的字符串,那么会抛出异样。* */
Week week = Enum.valueOf(Week.class,Week.MONDAY.name().toString());
Week week1 = Week.valueOf(Week.class,Week.MONDAY.name());
System.out.println("Enum.valueOf,"+week);//MONDAY
System.out.println("Week.valueOf,"+week1);//MONDAY
//3、values()
System.out.println("Week.values(),"+Weekday.values());
// 返回一个 Weekday 数组,[Ljavase.enumeration.Weekday;@2a84aee7
//4、通过 compareTo 办法比拟, 实际上其外部是通过 ordinal()值比拟的
System.out.println("Weekday.MONDAY.compareTo(Weekday.TUESDAY),"+Weekday.MONDAY.compareTo(Weekday.TUESDAY));
//false
//5、获取该枚举对象的 Class 对象援用, 当然也能够通过 getClass 办法
Class<?> declaringClass = Weekday.MONDAY.getDeclaringClass();
System.out.println("获取该枚举对象的 Class 对象援用,"+declaringClass);
//javase.enumeration.Weekday
//6、通过 getEnumConstants()获取该枚举类型的所有元素,如果 Class 对象不是枚举类型,则返回 null。Object[] enumConstants = declaringClass.getEnumConstants();
// 枚举类个数,Weekday.values().length)
for (int i = 0; i < Weekday.values().length; i++) {System.out.println("getEnumConstants,"+enumConstants[i]);
//SUNDAY、MONDAY、TUESDAY、WEDNESDAY、THURSDAY、FRIDAY、SATURDAY
}
//7、判断是否是枚举类型
System.out.println("declaringClass.isEnum(),"+declaringClass.isEnum());//true
//8、获取枚举变量的属性
System.out.println("编号,"+Week.MONDAY.getId()+", 含意,"+Week.MONDAY.getMeaning());
}
4、向上转型
这个货色意义何在,有待钻研。
5、局部办法源码介绍
(1)valueof
(2)compareTo
五、枚举类中定义形象办法
1、定义形象办法
2、测试类
3、控制台输入
六、实现接口
1、接口
2、实现接口
3、测试类
//10、实现接口并调用接口中办法
MONDAY.StudyDataStrucure();
4、控制台输入
七、枚举实现单例
枚举单例(Enum Singleton)在 Effective Java 一书中提到,因为其功能完善,应用简洁,无偿地提供了序列化机制,在面对简单的序列化或者反射攻打时仍然能够相对避免屡次实例化等长处,被作者所推崇。
八、EnumMap
1、代码实例剖析 EnumMap 和 HashMap
以 1 月到 6 月学习不同的 Java 我的项目为例。
2、控制台输入
3、后果剖析
HashMap 比照 EnumMap
HashMap 和 EnumMap 的输入后果统一,证实枚举类型都能够应用,然而 EnumMap 作为枚举的专属的汇合,咱们没有理由再去应用 HashMap,毕竟 EnumMap 要求其 Key 必须为 Enum 类型。
因为枚举类型实例的数量绝对固定并且无限,所以 EnumMap 应用数组来寄存与枚举类型对应的值,毕竟数组是一段间断的内存空间,依据程序局部性原理,效率会相当高。
EnumMap 须要传递一个类型信息,即 Class 对象,通过这个参数 EnumMap 就能够依据类型信息初始化器外部数据结构,也能够初始化时传入一个 Map 汇合。
key 值不能为 null。
4、简略的源码剖析
(1)EnumMap 继承了 AbstractMap 类,因而 EnumMap 具备个别 map 的应用办法。
(2)因为 key 值根本固定,底层数组实现,效率更高
(3)获取 key 数组办法
(4)put()
(5)get()
(6)remove()
(7)containsKey()
以上就是 EnumMap 的源码剖析,即外部有两个数组,长度雷同,一个是以枚举为 key 的数组,一个是对应的值数组,key 不容许 null,value 能够为 null,键都有一个对应的索引,依据索引间接拜访和操作其键数组和值数组,因为操作时都是数组,所以效率比 HashMap 高。
小结:
枚举除了不能继承,基本上能够将 enum 看做一个惯例的类,Java 不容许应用为枚举常量赋值,enum 能够通过办法来显示赋值,能够增加一般办法、静态方法、形象办法、构造方法。枚举能够实现接口,因为 enum 实际上都继承自 java.lang.Enum 类,而 Java 不反对多重继承,所以 enum 不能再继承其余类,当然也不能继承另一个 enum。
今日份分享已完结,请大家多多包涵和指导!