今日分享开始啦,请大家多多指教~
今日次要分享的是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。
今日份分享已完结,请大家多多包涵和指导!