历史
枚举是JDK1.5版本新增的特性(泛型、For-each等如今被广泛应用的特性也是由JDK1.5时所新增的),另外到了JDK1.6后switch语句支持枚举类型。
枚举概念
它是一种新的类型,允许用常量来表示特定的数据片断,而且全部都以类型安全的形式来表示。
常量的使用
在JDK1.5之前,我们定义常量都是:public static fianl....。现在好了,有了枚举,可以把相关的常量分组到一个枚举类型里,
好处:
枚举类型是Java 5中新增特性的一部分,它是一种特殊的数据类型,之所以特殊是因为它既是一种类(class)类型却又比类类型多了些特殊的约束,但是这些约束的存在也造就了枚举类型的简洁性、安全性以及便捷性。
语法解析
1 最最最简单版
public enum ColorEnum {
RED,BLUE,GREEN
}
通过工具解析class后获得的源代码(工具参考上面的链接)
public final class ColorEnum extends Enum
{
//返回存储枚举实例的数组的副本。values()方法通常用于foreach循环遍历枚举常量。
public static ColorEnum[] values()
{
return (ColorEnum[])$VALUES.clone();
}
//根据实例名获取实例
public static ColorEnum valueOf(String s)
{
return (ColorEnum)Enum.valueOf(ColorEnum, s);
}
//私有构造方法,这里调用了父类的构造方法,其中参数s对应了常量名,参数i代表枚举的一个顺序(这个顺序与枚举的声明顺序对应,用于oridinal()方法返回顺序值)
private ColorEnum(String s, int i)
{
super(s, i);
}
//我们定义的枚举在这里声明了三个 ColorEnum的常量对象引用,对象的实例化在static静态块中
public static final ColorEnum RED;
public static final ColorEnum BLUE;
public static final ColorEnum GREEN;
//将所有枚举的实例存放在数组中
private static final ColorEnum $VALUES[];
static
{
RED = new ColorEnum("RED", 0);
BLUE = new ColorEnum("BLUE", 1);
GREEN = new ColorEnum("GREEN", 2);
//将所有枚举的实例存放在数组中
$VALUES = (new ColorEnum[] {
RED, BLUE, GREEN
});
}
}
自定义函数
package com;
public enum Color {
RED("红色", 1), GREEN("绿色", 2), BLANK("白色", 3), YELLO("黄色", 4);
private String name ;
private int index ;
private Color( String name , int index ){
this.name = name ;
this.index = index ;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getIndex() {
return index;
}
public void setIndex(int index) {
this.index = index;
}
}
枚举的好处以及与常量类的区别
1)枚举型可以直接与数据库打交道,我通常使用varchar类型存储,对应的是枚举的常量名。(数据库中好像也有枚举类型,不过也没用过)
2) switch语句支持枚举型,当switch使用int、String类型时,由于值的不稳定性往往会有越界的现象,对于这个的处理往往只能通过if条件筛选以及default模块来处理。而使用枚举型后,在编译期间限定类型,不允许发生越界的情况
3) 当你使用常量类时,往往得通过equals去判断两者是否相等,使用枚举的话由于常量值地址唯一,可以用==直接对比,性能会有提高
4) 常量类编译时,是直接把常量的值编译到类的二进制代码里,常量的值在升级中变化后,需要重新编译引用常量的类,因为里面存的是旧值。枚举类编译时,没有把常量值编译到代码里,即使常量的值发生变化,也不会影响引用常量的类。
5)枚举类编译后默认为final class,不允许继承可防止被子类修改。常量类可被继承修改、增加字段等,容易导致父类的不兼容。
values()获取存储枚举中所有常量实例的数组。常配合foreach完成遍历
for( Color color : Color.values()){
System.out.println( color + " name: " + color.getName() + " index: " + color.getIndex() );
}
获取某一实例的值
System.out.println( Color.RED.getName() );
valueOf()通过常量名获取对应的枚举实例。
ColorEnum red = ColorEnum.valueOf("RED");
getEnumConstants()方法,同样可以轻而易举地获取所有枚举实例变量
Class<?> clasz = e.getDeclaringClass();
if(clasz.isEnum()) {
Day[] dsz = (Day[]) clasz.getEnumConstants();
System.out.println("dsz:"+Arrays.toString(dsz));
}
enumConstantDirectory方法获取到的是一个Map集合,在该集合中存放了以枚举name为key和以枚举实例变量为value的Key&Value数据
T result = enumType.enumConstantDirectory().get(name);
//创建一个具有指定键类型的空枚举映射。
EnumMap(Class<K> keyType)
//创建一个其键类型与指定枚举映射相同的枚举映射,最初包含相同的映射关系(如果有的话)。
EnumMap(EnumMap<K,? extends V> m)
//创建一个枚举映射,从指定映射对其初始化。
EnumMap(Map<K,? extends V> m)
//使用第一种构造
Map<Color,Integer> enumMap=new EnumMap<>(Color.class);
//使用第二种构造
Map<Color,Integer> enumMap2=new EnumMap<>(enumMap);
//使用第三种构造
Map<Color,Integer> hashMap = new HashMap<>();
hashMap.put(Color.GREEN, 2);
hashMap.put(Color.BLUE, 3);
Map<Color, Integer> enumMap = new EnumMap<>(hashMap);
EnumMap继承了AbstractMap类,因此EnumMap具备一般map的使用方法,keyType表示类型信息,keyUniverse表示键数组,存储的是所有可能的枚举值,vals数组表示键对应的值,size表示键值对个数。在构造函数中通过keyUniverse = getKeyUniverse(keyType);初始化了keyUniverse数组的值,内部存储的是所有可能的枚举值,接着初始化了存在Value值得数组vals,其大小与枚举实例的个数相同,getKeyUniverse方法实现如下
EnumSet是与枚举类型一起使用的专用 Set 集合,EnumSet 中所有元素都必须是枚举类型。与其他Set接口的实现类HashSet/TreeSet(内部都是用对应的HashMap/TreeMap实现的)不同的是,EnumSet在内部实现是位向量(稍后分析)
创建一个具有指定元素类型的空EnumSet。
EnumSet<E> noneOf(Class<E> elementType)
//创建一个指定元素类型并包含所有枚举值的EnumSet
<E extends Enum<E>> EnumSet<E> allOf(Class<E> elementType)
// 创建一个包括枚举值中指定范围元素的EnumSet
<E extends Enum<E>> EnumSet<E> range(E from, E to)
// 初始集合包括指定集合的补集
<E extends Enum<E>> EnumSet<E> complementOf(EnumSet<E> s)
// 创建一个包括参数中所有元素的EnumSet
<E extends Enum<E>> EnumSet<E> of(E e)
<E extends Enum<E>> EnumSet<E> of(E e1, E e2)
<E extends Enum<E>> EnumSet<E> of(E e1, E e2, E e3)
<E extends Enum<E>> EnumSet<E> of(E e1, E e2, E e3, E e4)
<E extends Enum<E>> EnumSet<E> of(E e1, E e2, E e3, E e4, E e5)
<E extends Enum<E>> EnumSet<E> of(E first, E... rest)
//创建一个包含参数容器中的所有元素的EnumSet
<E extends Enum<E>> EnumSet<E> copyOf(EnumSet<E> s)
<E extends Enum<E>> EnumSet<E> copyOf(Collection<E> c)
版权声明:本文为博主原创文章,转载请附上博文链接!
---------------------
转载地址:https://blog.csdn.net/javazejian/article/details/71333103