1. 基本方法:
values: 可以遍历enum实例,返回enum实例的数组。
ordinal: 返回int 值,enum实例在声明时的次序,从0开始。
getDeclaringClass:得到实例所属的enum类。
name: 返回实例声明时的名字,等价于toString.
valueOf: 根据名字返回响应的enum实例,是static方法,如果不存在该名字,则抛出异常。
创建Enum实例时,编译器会生成继承于java.lang.Enum的类
Enum类实现了Comparable 和Serializable接口。
Enum类不能被继承。
enum的内部定义构造器一般为private,即使不是private,也只能在enmu的内部创建enum实例。
例子:
enum specialData
{
PSPROFILECHECK("PowerSuite Profile Check"),
DIFFAIRPORTCHECK("Different Airports Check"),
TRAVLEDOCUMENT("Travel Document"),
CALLCARDVALIDATE("Calling Card Validation");
private String context;
private String getContext()
{
return this.context;
}
private specialData(String Context)
{
this.context = Context;
}
public String toString()
{
return this.context;
}
};
2. 特别的:
(1)enum 类继承于Enum类,但是Enum并没有values()方法。
原因:values()是由编译器自动添加的static方法,编译器同时还添加了只含有一个餐食的valueOf(Enum中的valueOf含有两个参数。)
(2)编译器会自动将enum类标记为final类
(3)Class中有个getEnumConstants()方法可以获取Enum的所有enum实例。
摘自《java 编程思想》
enum Explore{HERE,THERE}
public class EnumReflection {
public static Set<String> analyze(Class<?> enumClass)
{
System.out.println("------Analyzing " + enumClass + "--------");
System.out.println("Interface");
for(Type t : enumClass.getGenericInterfaces())
{
System.out.println(t);
}
System.out.println("Base: " + enumClass.getSuperclass());
System.out.println("Methods: ");
Set<String> methods = new TreeSet<String>();
for(Method m : enumClass.getMethods())
{
methods.add(m.getName());
}
System.out.println(methods);
return methods;
}
public static void main(String[] args)
{
Set<String> exploreMethods = analyze(Explore.class);
Set<String> enumMethods = analyze(Enum.class);
System.out.println("Explore.containsAll(Enum)?" + exploreMethods.containsAll(enumMethods));
System.out.println("exploreMethods.removeAll(enumMethods)");
exploreMethods.removeAll(enumMethods);
System.out.println(exploreMethods);
OsExecute.command("javap Explore");
}
}
3. Enum VS EnumSet:
(1)Enum是不能添加删除的Set,和Set一样成员唯一。
(2)EnumSet的原理:位向量,位向量能表示的元素个数与向量长度有关,一个byte可以表示8个元素,一个long型可以表示64个元素。
(3)EnumSet源码:
public abstract class EnumSet<E extends Enum<E>> extends AbstractSet<E>
implements Cloneable, java.io.Serializable
{
final Class<E> elementType;//类型信息
final Enum<?>[] universe;//所有的枚举
private static Enum<?>[] ZERO_LENGTH_ENUM_ARRAY = new Enum<?>[0];
EnumSet(Class<E>elementType, Enum<?>[] universe) {
this.elementType = elementType;
this.universe = universe;
}
public static <E extends Enum<E>> EnumSet<E> noneOf(Class<E> elementType) {
Enum<?>[] universe = getUniverse(elementType);
if (universe == null)
throw new ClassCastException(elementType + " not an enum");
if (universe.length <= 64)
return new RegularEnumSet<>(elementType, universe);
else
return new JumboEnumSet<>(elementType, universe);
}
public static <E extends Enum<E>> EnumSet<E> allOf(Class<E> elementType) {
EnumSet<E> result = noneOf(elementType);
result.addAll();
return result;
}
abstract void addAll();
public static <E extends Enum<E>> EnumSet<E> copyOf(EnumSet<E> s) {
return s.clone();
}
/**
* Returns all of the values comprising E.
* The result is uncloned, cached, and shared by all callers.
*/
private static <E extends Enum<E>> E[] getUniverse(Class<E> elementType) {
return SharedSecrets.getJavaLangAccess()
.getEnumConstantsShared(elementType);
}
/**
* This class is used to serialize all EnumSet instances, regardless of
* implementation type. It captures their "logical contents" and they
* are reconstructed using public static factories. This is necessary
* to ensure that the existence of a particular implementation type is
* an implementation detail.
*
* @serial include
*/
private static class SerializationProxy <E extends Enum<E>>
implements java.io.Serializable
{
/**
* The element type of this enum set.
*
* @serial
*/
private final Class<E> elementType;
/**
* The elements contained in this enum set.
*
* @serial
*/
private final Enum<?>[] elements;
SerializationProxy(EnumSet<E> set) {
elementType = set.elementType;
elements = set.toArray(ZERO_LENGTH_ENUM_ARRAY);
}
// instead of cast to E, we should perhaps use elementType.cast()
// to avoid injection of forged stream, but it will slow the implementation
@SuppressWarnings("unchecked")
private Object readResolve() {
EnumSet<E> result = EnumSet.noneOf(elementType);
for (Enum<?> e : elements)
result.add((E)e);
return result;
}
private static final long serialVersionUID = 362491234563181265L;
}
Object writeReplace() {
return new SerializationProxy<>(this);
}
// readObject method for the serialization proxy pattern
// See Effective Java, Second Ed., Item 78.
private void readObject(java.io.ObjectInputStream stream)
throws java.io.InvalidObjectException {
throw new java.io.InvalidObjectException("Proxy required");
}
}
从源码中可以看出,EnumSet可以存储多于64个的元素。
所谓的add就是将对应元素设置为1,再与原来的值相或。
优点:节省空间,比Set效率高。
4.EnumMap
和Map的差别就是EnumMap的key值必须来源于enum类型,并且EnumMap保证顺序。