java枚举初学习

历史

枚举是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

 

猜你喜欢

转载自blog.csdn.net/qq_25744257/article/details/84396748