原创文章,转载请标注出处:http://www.javashuo.com/article/p-sorpszpw-dx.htmlhtml
枚举就是一个语法糖效果。java
定义一个枚举,其实就是定义一个继承抽象类Enum的类。数组
了解了Enum,就能了解枚举。this
public abstract class Enum<E extends Enum<E>> implements Comparable<E>, Serializable {}
枚举类实现了Comparable和Serializable接口,那么也就意味着,每一个枚举类都拥有比较(有序)和序列化功能。code
public abstract class Enum<E extends Enum<E>> implements Comparable<E>, Serializable { private final String name; private final int ordinal; public final String name() { return name; } public final int ordinal() { return ordinal; } }
这两个属性是枚举的内置属性,name表示的是枚举值的名称,ordinal表示的是枚举值的序号。htm
其做用后面再说blog
public abstract class Enum<E extends Enum<E>> implements Comparable<E>, Serializable { protected Enum(String name, int ordinal) { this.name = name; this.ordinal = ordinal; } }
Enum中只有这一个构造器,其申明为protected就是为了继承它的子类(咱们定义的各类枚举)来调用的。继承
public abstract class Enum<E extends Enum<E>> implements Comparable<E>, Serializable { public final boolean equals(Object other) { return this==other; } }
默认的equals方法底层就是使用==实现的,因此在枚举的比较使用equals和==都是能够的。前提是没有在枚举类中重写equals方法。接口
咱们能够在自定义的枚举类中重写该方法,来实现咱们本身的比较方式。字符串
public abstract class Enum<E extends Enum<E>> implements Comparable<E>, Serializable { protected final Object clone() throws CloneNotSupportedException { throw new CloneNotSupportedException(); } protected final void finalize() { } private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { throw new InvalidObjectException("can't deserialize enum"); } private void readObjectNoData() throws ObjectStreamException { throw new InvalidObjectException("can't deserialize enum"); } }
这四个方法均是被禁用的方法:
序列化中禁用readObject和readObjectNoData方法:目的为了保证单例惟一
public abstract class Enum<E extends Enum<E>> implements Comparable<E>, Serializable { 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; } }
这是实现了接口Comparable中的方法。用于定义比较的方式,能够看出这里是使用枚举值的序号做为比较条件的。
public abstract class Enum<E extends Enum<E>> implements Comparable<E>, Serializable { 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); } }
该方法的做用是获取到指定枚举类型中指定枚举名称的枚举值。
枚举是一种编译器语法糖。
咱们使用enum关键字定义一个枚举,编译以后,编译器会对其进行加工,具体以下:
经过上面一些列加工以后,枚举类被解析为一个普通的类,类名不变。