java枚举

匿名 (未验证) 提交于 2019-12-02 21:52:03

1、为何使用Java枚举


Java5之前没有enum的情况下,我们一般使用几个int常量表示枚举值(int枚举类型)或者string枚举类型

public static final ZOO_CAT=1 #表示小猫

public static final ZOO_CAT=2 #表示小狗

作为方法参数zooType是int类型

如 public void printZoo(int zooType){

}

这样的话 我们调用方法只要是int类型就行 ,没法控制方法调用的安全性

其次 作为一个数字 如果打印到日志是个裸数字没有可读性

为此 java5 产生了enum 固定且有限的类型都可以使用enum。

2、如何使用java枚举


package com.yangfei.test.meiju;  public class EnumYf {     enum ZOO{         CAT,DOG,PIG     }      public static void printZoo(ZOO zooType){         System.out.println("my name is " + zooType);     }      public static void main(String[] args){         printZoo(ZOO.DOG);     } }
View Code

如上 一个简单的例子 EnumYf中定义了一个动作枚举类型。

当一个枚举是公共的分类时 我们应该定义单独的文件定义,如:

public enum xxx{

}

3、枚举实际就是类


3.1 枚举就是一个类

定义一个enum

package com.yangfei.test.meiju;  public class EnumYf {     enum ZOO{         CAT,DOG,PIG     }      public static void printZoo(ZOO zooType){         System.out.println("my name is " + zooType);     }      public static void main(String[] args){         printZoo(ZOO.DOG);         System.out.println(ZooEnum.CAT);     } }
View Code

对编译生成的class文件 使用javap -p -c xx.class查看生成的字节码文件:

可以看到:

  • 构造方法时private 表面枚举是没法外部在new一个新对象的
  • 枚举值实际就是当前类的几个常量实例

所以我们使用枚举是没法再继承其他类的,但可以实现接口。

3.2 我们再看看Enum抽象类的结构

实现了Comparable和Serializable接口 表面Enum是有内在的排序和可序列化的

a. compareTo方法

public final int compareTo(E o) {         Enum<?> other = (Enum<?>)o;         Enum<E> self = this;         if (self.getClass() != other.getClass() && // optimization             self.getDeclaringClass() != other.getDeclaringClass())             throw new ClassCastException();         return self.ordinal - other.ordinal;     } 

  compareTo实际比较的是ordinal

b. ordinal方法

外部不要轻易使用ordinal(万一枚举定义顺序变了咋办!)

/**      * The ordinal of this enumeration constant (its position      * in the enum declaration, where the initial constant is assigned      * an ordinal of zero).      *      * Most programmers will have no use for this field.  It is designed      * for use by sophisticated enum-based data structures, such as      * {@link java.util.EnumSet} and {@link java.util.EnumMap}.      */     private final int ordinal; 

4、枚举常用场景


4.2 作为方法的入参

public class EnumYf {     public static void printZoo(ZooEnum zooEnum){         System.out.println(zooEnum.name());     }     public static void main(String[] args){         printZoo(ZooEnum.DOG);     } }
View Code

4.3 switch判断

public class EnumYf {     public static void printZoo(ZooEnum zooEnum){         switch (zooEnum){             case DOG:                 System.out.println("this is dog");                 break;             case CAT:                 System.out.println("this is cat");                 break;             case PIG:                 System.out.println("this is pig");                 break;         }     }     public static void main(String[] args){         printZoo(ZooEnum.DOG);     } }
View Code

5、枚举的序列化


但枚举的序列化比较特殊,序列化时只会将枚举的name(就是一字符串)序列化

反序列时 根据枚举的valueOf(String name)找到对应的枚举常量,也就是说即使反序列化也不会生成新的实例

这点对单例模式就有绝对的保护 ,单例默认参考博主另一篇博文:https://www.cnblogs.com/yangfei629/p/11370732.html

6、特定于常量的方法实现

7、枚举实现接口

8、EnumSet和EnumMap

TODO

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!