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); } }
如上 一个简单的例子 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); } }
对编译生成的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); } }
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); } }
5、枚举的序列化
但枚举的序列化比较特殊,序列化时只会将枚举的name(就是一字符串)序列化
反序列时 根据枚举的valueOf(String name)找到对应的枚举常量,也就是说即使反序列化也不会生成新的实例
这点对单例模式就有绝对的保护 ,单例默认参考博主另一篇博文:https://www.cnblogs.com/yangfei629/p/11370732.html
6、特定于常量的方法实现
7、枚举实现接口
8、EnumSet和EnumMap
TODO
来源:博客园
作者:杨飞随笔
链接:https://www.cnblogs.com/yangfei629/p/11406682.html