枚举是指将变量的值一一列举出来,变量的值只限于列举出的范围
如,一周只有7天,一年只有12个月
与单例模式不同的是,枚举中可以有一个以上的实例
模拟枚举 首先将自定义枚举类的构造私有化
然后创建若干静态常量对象供外界访问1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 public class Direction { public static final Direction FRONT = new Direction("前" ); public static final Direction BEHIND = new Direction("后" ); public static final Direction LEFT = new Direction("左" ); public static final Direction RIGHT = new Direction("右" ); private String name; private Direction (String name) {this .name = name;} public String getName () {return name;} } public static void main (String[] args) { Direction front = Direction.FRONT; System.out.println(front); System.out.println(front.getName()); Direction behind = Direction.BEHIND; System.out.println(behind.getName()); Direction left = Direction.LEFT; System.out.println(left.getName()); Direction right = Direction.RIGHT; System.out.println(right.getName()); }
执行结果如下 :
枚举 若自己定义枚举,其实是很麻烦的
在JDK5,java为我们提供了枚举类
格式为 :
public enum 枚举类名{
枚举项1,枚举项2,..;
}
简单的实例如下 :1 2 3 4 5 6 7 public enum Enum01 { FRONT,BEHIND,LEFT,RIGHT; } public static void main (String[] args) { Enum01 enum01 = Enum01.FRONT; System.out.println(enum01); }
可以看到打印的是枚举实例的名字
结果如下 :
为什么会产生这样的结果呢?
其实枚举是java为我们作了封装
省去了我们自己创建枚举的设计过程
使得代码更加简洁,打开枚举的字节码文件
可以发现,需要了解枚举类才行
结果如下 : 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 package cn._03_enum;public final class Enum01 extends Enum { public static final Enum01 FRONT; public static final Enum01 BEHIND; public static final Enum01 LEFT; public static final Enum01 RIGHT; private static final Enum01 $VALUES[]; public static Enum01[] values(){ return (Enum01[])$VALUES.clone(); } public static Enum01 valueOf (String name) { return (Enum01)Enum.valueOf(cn/_03_enum/Enum01, name); } private Enum01 (String s, int i) {super (s, i);} static { FRONT = new Enum01("FRONT" , 0 ); BEHIND = new Enum01("BEHIND" , 1 ); LEFT = new Enum01("LEFT" , 2 ); RIGHT = new Enum01("RIGHT" , 3 ); $VALUES = (new Enum01[] { FRONT, BEHIND, LEFT, RIGHT }); } }
Enum<E extends Enum>类 该类是所有Java语言枚举类型的公共基本类1 2 public abstract class Enum <E extends Enum <E >> extends Objectimplements Comparable <E >, Serializable
构造方法 单独的构造方法,用于响应枚举类型声明的编译器发出的代码1 protected Enum (String name, int ordinal)
需要知道的是 classes是无法直接继承Enum类的成员方法 枚举类无法克隆,重写了Cloneable的clone方法
直接抛出CloneNotSupportedException1 2 3 protected final Object clone () throws CloneNotSupportedException { throw new CloneNotSupportedException(); }
public final int compareTo(E o)
比较枚举的序号,也就是元素的位置
通过class文件解析也发现了,第一个元素为0...n1 2 3 4 5 6 7 8 public final int compareTo (E o) { Enum<?> other = (Enum<?>)o; Enum<E> self = this ; if (self.getClass() != other.getClass() && self.getDeclaringClass() != other.getDeclaringClass()) throw new ClassCastException(); return self.ordinal - other.ordinal; }
equals方法对Object作了重写
但是也是比较的内存地址1 2 3 public final boolean equals (Object other) { return this ==other; }
枚举类是不能有finalize方法的1 protected final void finalize () { }
getDeclaringClass获取声明的枚举类型
判断两个枚举常量是否类型一致的时候
若它们同时继承自枚举类,则返回其枚举类型
若继承自枚举类的一个子类,则返回其父类1 2 3 4 5 public final Class<E> getDeclaringClass () { Class<?> clazz = getClass(); Class<?> zuper = clazz.getSuperclass(); return (zuper == Enum.class) ? (Class<E>)clazz : (Class<E>)zuper; }
这主要针对的是枚举类可能出现的匿名内部类的情况
简单的案例测试如下 :1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 public enum Cat{ WHITH(){ @Override public void fun () {System.out.println("白喵,喵喵~" );} },BLACK; public void fun () {System.out.println("喵喵~" );} } public enum Dog { WHITH,BLACK; } public static void main (String[] args) { Class c1 = Cat.BLACK.getDeclaringClass(); Class d1 = Dog.BLACK.getDeclaringClass(); System.out.println(c1 == d1); Class c2 = Cat.WHITH.getDeclaringClass(); Class d2 = Dog.WHITH.getDeclaringClass(); System.out.println(c1 == c2); System.out.println(d1 == d2); }
执行结果如下 :
hashCode方法就是Object的,返回内存地址的哈希值
name方法返回枚举常量的名称与toString一样1 2 3 4 5 6 public final String name () { return name; } public String toString () { return name; }
ordinal方法返回该常量在这个枚举类型中的序数1 2 3 public final int ordinal () { return ordinal; }
valueOf方法通过枚举字节码对象以及名称获取该常量1 2 3 4 5 6 7 8 9 public static <T extends Enum<T>> T valueOf (Class<T> enumType, String name) { T result = enumType.enumConstantDirectory().get(name); if (result != null ) return result; if (name == null ) throw new NullPointerException("Name is null" ); throw new IllegalArgumentException( "No enum constant " + enumType.getCanonicalName() + "." + name); }
仍然沿用猫的枚举类,调用其fun方法
可以发现打印出 白喵,喵喵~
简单案例如下 :1 2 3 public static void main (String[] args) { Enum.valueOf(Cat.class,"WHITH" ).fun(); }