JAVA中的枚举类型
2016-05-25 17:54
381 查看
提要:
1.枚举类型介绍与简单使用
2.枚举类型中常用的方法
3.枚举类型嵌套
4.EnumSet与EnumMap
创建enum时,编译器会为你生成一个相关的类,这个类继承自Enum,在这个类里每个枚举实例都是一个static final的LikeClasses类的对象。
除了不能继承之外,enum拥有几乎所有类的特性,比如说它可以添加成员变量成员方法和构造方法(构造方法只能是private),并且为它们使用修饰符(默认是default范围)。
之所以提倡使用枚举而不是static final变量这种形式的常量,是因为常量①可读性不好②无法保证类型安全
示例:
调用toString()方法,可以打印枚举实例的名称。
调用valueOf()方法,可以根据名字获得枚举实例。
调用ordinal()方法,可以取得枚举实例的次序。
举个栗子:
重点在于Class的getEnumConstants方法,该方法专用于枚举类型,返回其枚举实例。但这种方式并没有直观的组织化,Dessert和Coffee并没有在语法上归为同一类,Food的枚举实例也可以接受除了这两个枚举之外的任何枚举类型参数。因此考虑用interface作为中介,使Dessert和Coffee实现同一个接口,并且Food只接受这个接口的实现类:
和大多数集合类一样,EnumSet是不同步的。
EnumSet通过自身的多个静态方法创建实例。其中EnumSet有多个重载的of方法,在枚举实例个数为2~5个时候都可以使用固定参数的of方法,超过5个则使用可变参数的of方法,这样做的原因是可变参数对比显式的参数,在性能上会有一点损失。
EnumSet的底层实现是long,一个long值占64位空间,而一个enum实例只需一个bit位表示其是否存在,如果enum元素多过64个bit,EnumSet会用一个
new long[(universe.length + 63) >>> 6]
EnumMap用来自同一个枚举类型的枚举实例作为键,除了键只能是枚举类型这一个限制,其他跟Map差不多。
EnumMap在内部表现为数组。
1.枚举类型介绍与简单使用
2.枚举类型中常用的方法
3.枚举类型嵌套
4.EnumSet与EnumMap
1.枚举类型介绍与简单使用
从java 1.5开始有的枚举类型,基本使用方法是用enum关键字定义。创建enum时,编译器会为你生成一个相关的类,这个类继承自Enum,在这个类里每个枚举实例都是一个static final的LikeClasses类的对象。
除了不能继承之外,enum拥有几乎所有类的特性,比如说它可以添加成员变量成员方法和构造方法(构造方法只能是private),并且为它们使用修饰符(默认是default范围)。
之所以提倡使用枚举而不是static final变量这种形式的常量,是因为常量①可读性不好②无法保证类型安全
示例:
public enum Test{ T1("1"),T2("2"); static String s1 = "s1"; static String s2 = "s2"; Test(String s){ System.out.println(s); print(); } public static void plus(){ System.out.println(s1 + s2); } private void print(){ System.out.printf("%s,%s\n",s1,s2); } } public static void main(String[] args){ Test test = Test.T1; test.plus(); switch (test) { case T1 : System.out.println(true); break; default : System.out.println(true); break; } } ---------------------------- 输出结果: 1 null,null 2 null,null<pre name="code" class="java">s1s2true
之所以会是null是因为static变量直到它所属的类第一次被加载时才会被加载,这里只是编译并没有使用,类没有被加载
2.枚举类型中常用的方法
调用values()方法,可以遍历enum实例。调用toString()方法,可以打印枚举实例的名称。
调用valueOf()方法,可以根据名字获得枚举实例。
调用ordinal()方法,可以取得枚举实例的次序。
举个栗子:
public class Test { public enum Fruit{ APPLE,ORANGE,TOMATO; } public static void main(String[] args){ for(Fruit fruit : Fruit.values()){ System.out.println(fruit.toString() + " is on " + fruit.ordinal()); } System.out.println("It's " + Fruit.valueOf("APPLE").toString()); } } ------------------------------------ 输出: APPLE is on 0 ORANGE is on 1 TOMATO is on 2 It's APPLE
3.枚举类型嵌套
枚举并不支持继承,但有时候会遇到这种情况:想要把多个枚举类型进行分组,并且使它们之间具有层次结构。比如:Food:{ DESSERT:{VEGETABLES, CAPCAKE}, COFFEE:{LATEE, TEA} }或许我可以建一个这样的枚举?
public class Test{ enum Food{ DESSERT(Dessert.class), COFFEE(Coffee.class); private Enum[] food; private Food(Class<?> eclass) { this.food = (Enum[]) eclass.getEnumConstants(); } public Enum[] getFood(){ return food; } } enum Dessert{ VEGETABLES, CAPCAKE } enum Coffee{ LATTE, TEA } public static void main(String args[]) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, InstantiationException{ Enum[] enums = Food.DESSERT.getFood(); for(Enum e : enums){ System.out.println(e.ordinal()); System.out.println(e.toString()); } } }
重点在于Class的getEnumConstants方法,该方法专用于枚举类型,返回其枚举实例。但这种方式并没有直观的组织化,Dessert和Coffee并没有在语法上归为同一类,Food的枚举实例也可以接受除了这两个枚举之外的任何枚举类型参数。因此考虑用interface作为中介,使Dessert和Coffee实现同一个接口,并且Food只接受这个接口的实现类:
public class Test{ public interface FoodIntef{ public enum Dessert implements FoodIntef{ VEGETABLES, CAPCAKE } public enum Coffee implements FoodIntef{ LATTE, TEA } } public enum Food{ DESSERT(FoodIntef.Dessert.class), COFFEE(FoodIntef.Coffee.class); private FoodIntef[] food; private Food(Class<? extends FoodIntef> food){ this.food = food.getEnumConstants(); } } }
4.EnumSet和EnumMap
EnumSet是专用于存储枚举类型的set,其中的所有键都必须来自同一个枚举类型。枚举实例在EnumSet内部以位向量的形式存储,因此非常紧凑和高效。和大多数集合类一样,EnumSet是不同步的。
EnumSet通过自身的多个静态方法创建实例。其中EnumSet有多个重载的of方法,在枚举实例个数为2~5个时候都可以使用固定参数的of方法,超过5个则使用可变参数的of方法,这样做的原因是可变参数对比显式的参数,在性能上会有一点损失。
EnumSet的底层实现是long,一个long值占64位空间,而一个enum实例只需一个bit位表示其是否存在,如果enum元素多过64个bit,EnumSet会用一个
new long[(universe.length + 63) >>> 6]
EnumMap用来自同一个枚举类型的枚举实例作为键,除了键只能是枚举类型这一个限制,其他跟Map差不多。
EnumMap在内部表现为数组。
相关文章推荐
- (java)Leetcode-15. 3Sum
- JAVA中的反射机制
- JAVA 笔记(三) 从源码深入浅出集合框架
- Struts2_类型转换错误消息的显示和定制
- RxJava介绍
- java 上传文件到七牛云存储的demo
- 【第九章】 Spring的事务 之 9.1 数据库事务概述 ——跟我学spring3
- Java面向对象经典总结
- Java程序的初始化顺序
- X的N次方 朴素分治法-Java
- java多线程调用run和不调用run的区别
- 如何用HotSwapAgent和DCEVM让java开发像js开发一样高效(JRebel的替代方案)
- Java内存泄漏--程序和内存的关系
- ROC曲线判别线性回归,java实现。
- JAVA多线程(五)用lock、synchronized、阻塞队列三种方法实现生产者消费者模式
- 大力推荐的超牛GitHub top 100的Java开源库
- 关于this关键字的用法
- javaIOzongji
- JAVA 三大GC(java6.0)
- Spring下jdbcTemplate增删改查总结