枚举
public enum EnumSingleton {
INSTANCE;
public void add() {
System.out.println("add方法...");
}
}
编译后的.class文件在target/classes目录
反编译.class文件工具下载与使用
链接:https://pan.baidu.com/s/18dTn8UCi5cxys4K2I6_1pw
提取码:derp
或者cmd使用javap -p 文件位置 进行反编译文件
反编译.class文件为EnumSingleton.java
public final class EnumSingleton extends Enum
{
public static EnumSingleton[] values()
{
return (EnumSingleton[])$VALUES.clone();
}
public static EnumSingleton valueOf(String name)
{
return (EnumSingleton)Enum.valueOf(com/mayikt/singleton/EnumSingleton, name);
}
private EnumSingleton(String s, int i)
{
super(s, i);
}
public void add()
{
System.out.println("add\u65B9\u6CD5...");
}
public static final EnumSingleton INSTANCE;
public static final EnumSingleton ANOTHER;
private static final EnumSingleton $VALUES[];
static
{
INSTANCE = new EnumSingleton("INSTANCE", 0);
ANOTHER = new EnumSingleton("ANOTHER", 1);
$VALUES = (new EnumSingleton[] {
INSTANCE, ANOTHER
});
}
}
由上面的代码可知,枚举的创建是在jvm加载的时候进行初始化的,由于是static的所以所有的对象只会加载一次且线程安全
Enum
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 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 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");
}
}
枚举不能被反射的原因
枚举不能被序列化的原因
我们知道,以前的所有的单例模式都有一个比较大的问题,就是一旦实现了Serializable接口之后,就不再是单例得了,因为,每次调用 readObject()方法返回的都是一个新创建出来的对象,有一种解决办法就是使用readResolve()方法来避免此事发生。但是,为了保证枚举类型像Java规范中所说的那样,每一个枚举类型极其定义的枚举变量在JVM中都是唯一的,在枚举类型的序列化和反序列化上,Java做了特殊的规定