public enum EnumSingleton {
/**
* 实例
*/
INSTANCE(new Object());
private Object obj;
EnumSingleton(Object obj) {
this.obj = obj;
}
public Object getObj() {
return obj;
}
}
这是一个枚举的单例,枚举类是在java中也是一种语法糖的形式,不然我们使用枚举对象的时候怎么会多了那么多方法,javac到底帮我们干了什么?我们使用JAD反编译工具来反编译一下这个枚举类
// 继承了一个名为Enum的类,所有的枚举类都会继承该类
// 每一个枚举对象的name属性和ordinal属性都是继承于这个对象
public final class EnumSingleton extends Enum
{
// 每一个实例都是static和final修饰的
public static final EnumSingleton INSTANCE;
private Object obj;
// 新增加的一个字段
private static final EnumSingleton $VALUES[];
// 获取所有枚举对象的数组
public static EnumSingleton[] values()
{
return (EnumSingleton[])$VALUES.clone();
}
// 新增加的一个方法,使用名字来获取对应的枚举对象
public static EnumSingleton valueOf(String name)
{
return (EnumSingleton)Enum.valueOf(EnumSingleton, name);
}
// 私有的构造方法,且方法签名发生了很大的变化,多了两个参数
private EnumSingleton(String s, int i, Object obj)
{
// 调用了父类的构造方法
super(s, i);
this.obj = obj;
}
public Object getObj()
{
return obj;
}
static
{
// 在静态代码块中初始化了枚举类中的每一个实例,也就是说加载好之后就初始化好了
// 且创建的顺序就是我们书写的顺序
// 所以说如果是使用枚举类实现的单例,是饿汉式的
INSTANCE = new EnumSingleton("INSTANCE", 0, new Object());
// 还额外创建了一个数组,用来保存我们的枚举对象
$VALUES = (new EnumSingleton[] {
INSTANCE
});
}
}
可以看出,不仅我们原有的方法得到了保留,还多了很多新的方法,这也就是一个枚举类的真实形态了
java中的Enum类,该类是一个抽象类
package java.lang;
import java.io.Serializable;
import java.io.IOException;
import java.io.InvalidObjectException;
import java.io.ObjectInputStream;
import java.io.ObjectStreamException;
public abstract class Enum<E extends Enum<E>>
implements Comparable<E>, Serializable {
private final String name;
public final String name() {
return name;
}
private final int ordinal;
public final int ordinal() {
return ordinal;
}
protected Enum(String name, int ordinal) {
this.name = name;
this.ordinal = ordinal;
}
public String toString() {
return name;
}
public final boolean equals(Object other) {
return this==other;
}
public final int hashCode() {
return super.hashCode();
}
protected final Object clone() throws CloneNotSupportedException {
throw new CloneNotSupportedException();
}
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;
}
public final Class<E> getDeclaringClass() {
Class<?> clazz = getClass();
Class<?> zuper = clazz.getSuperclass();
return (zuper == Enum.class) ? (Class<E>)clazz : (Class<E>)zuper;
}
public static <T extends Enum<T>> T valueOf(Class<T> enumType,
String name) {
// 调用了class对象的方法,该方法是枚举类特有的,在该方法中其实也就是调用了枚举类的values方法获取了所有的枚举对象,然后根据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 classes cannot have finalize methods.
*/
protected final void finalize() { }
/**
* prevent default deserialization
*/
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");
}
}
有一个想法,能不能用反射去修改枚举类内部初始化好的对象,尝试了一下,发现不可以
java中对使用static final修饰的属性的反射进行了限制,不能进行任何的修改
注意是static final而不是final或者static