Enum源代码解析
一简介
1.Enum源代码分析
2.关于Enum的单例模式
二.Enum源代码分析
1.类简介:
Enum是所有枚举类型的基类,包括EnumSet、EnumMap;
public abstract class Enum<E extends Enum<E>>
implements Comparable<E>, Serializable {
Enum类声明是abstract 类,但是不能被继承
我们看到作为积累Enum被继承是以下使用方式
public abstract class EnumSet<E extends Enum<E>> extends AbstractSet<E>
implements Cloneable, java.io.Serializable
而不是被直接继承继承
那么Enum作为abstract 有在声明时有什么用处呢,答案是以下:
enum Color {RED, BLUE, GREEN}
编译后
public final class Color extends Enum<Color> {
public static final Color[] values() { return (Color[])$VALUES.clone(); }
public static Color valueOf(String name) { ... }
private Color(String s, int i) { super(s, i); }
public static final Color RED;
public static final Color BLUE;
public static final Color GREEN;
private static final Color $VALUES[];
static {
RED = new Color("RED", 0);
BLUE = new Color("BLUE", 1);
GREEN = new Color("GREEN", 2);
$VALUES = (new Color[] { RED, BLUE, GREEN });
}
}
他是作为基类被继承的,然而是自动在编译后继承,这里涉及到另外两个只是点,
1> enum 作为abstract 类不能被new出来一个对象,需要通过以下方式
enum enumName{ value1,value2 method1(){} method2(){} }
2>enum 的构造方法不能被程序员调用,是提供给编译器响Enum类型的,这一点也保证了enum生来的单例模式
protected Enum(String name, int ordinal) {
this.name = name;
this.ordinal = ordinal;//这个参数一般是没什么用处,是在子类EnumSet等中使用的
}
2.成员变量
private final String name;//enum中的常量
private final int ordinal;//常量的序号,从0递增,子类EnumSet等中起到一定作用
3.finalize
protected final void finalize() { }
此方法在垃圾回收中使用到,对象想要逃过被回收的命运就需要在这个方法里面处理,但是这里写了空方法,并且子类不能重写。
4常用方法,
以enum Color {RED, BLUE, GREEN} 为例
通过Color.RED.methodName(params…)的方式调用
1>.toString()
public String toString() {
return name;
}
必要的时候可以覆盖方法,使用更加"programmer-friendly",程序员友好的方式
2>.equals(Object other)
public final boolean equals(Object other) {
return this==other;
}
如果常量相等返回true
3>.hashCode()
public final int hashCode() {
return super.hashCode();
}
返回常量的hash码
4>.compareTo(E o)
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;
}
在同个Enum类中进行对比,返回ordinal的差值,注意同个Enum类对比才有意义,不同的类进行对比,可能因为序号相同,导致不同的常量相等的情况。
5>valueOf
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的单例模式
Enum是天生的单例模式,
1.构造器只能别编译器调用,
2.实现了Serializable接口,但是不能通过序列化生成对象,如下
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");
}
3. clone()不能通过clone的方式生成对象
protected final Object clone() throws CloneNotSupportedException {
throw new CloneNotSupportedException();
}
- 3D游戏常用技巧Normal Mapping (法线贴图)原理解析——高级篇
- 使用 dynamic 标记解析JSON字符串 JDynamic :支持Json反序列化为Dynamic对象
- Java中Object类的equals()和hashCode()方法深入解析
- Mysql Join语法解析与性能分析
- 浅谈Android中的json解析
- RocketMQ原理解析-Remoting3.通信层整体交互图
- Android中widget的应用【安卓源码解析三】
- 字节流解析
- 几种常见加密算法解析及使用
- Java数据结构与算法解析——2-3树
- java注解,通过反射解析注解,模仿hibernate,获取sql语句。
- AsyncTask执行流程解析图片
- C++生成和解析XML文件的讲解
- iOS 数据解析 JSON XML
- 【2016年Esri开发者大会亮点解析】ArcGIS平台综述
- XML解析的两种方式DOM和SAX
- Android Window类解析
- Spring IOC原理解析
- 使用CMarkup创建及解析XML文档
- SQL Server 深入解析索引存储(中)