java enum 单例模式_枚举实现单例模式

枚举实现单例模式

前面我们说到序列化和反序列化以及反射对单例都是有破坏的,下面我们介绍一种更加优雅的实现,也是effective java中推荐的实现方式,枚举实现单例模式。话不多说我们直接看代码吧。

public enum EnumInstance {

INSTANCE{

protected void printTest(){

System.out.println("redstar Print SingletonTest");

}

};

protected abstract void printTest();

private Object data;

public Object getData() {

return data;

}

public void setData(Object data) {

this.data = data;

}

public static EnumInstance getInstance(){

return INSTANCE;

}

}

然后我们看看测试类

public class SingletonTest {

public static void main(String[] args) throws IOException, ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {

EnumInstance instance = EnumInstance.getInstance();

instance.setData(new Object());

ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("singleton_file"));

oos.writeObject(instance);

File file = new File("singleton_file");

ObjectInputStream ois = new ObjectInputStream(new FileInputStream(file));

EnumInstance newInstance = (EnumInstance) ois.readObject();

System.out.println(instance.getData());

System.out.println(newInstance.getData());

System.out.println(instance.getData() == newInstance.getData());

}

这里返回的结果是true,然后我们测试一下反射去获取这个对象。

public class SingletonTest {

public static void main(String[] args) throws IOException, ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {

Class objectClass = EnumInstance.class;

Constructor constructor = objectClass.getDeclaredConstructor(String.class,int.class);

constructor.setAccessible(true);

EnumInstance instance = (EnumInstance) constructor.newInstance("redstar",666);

}

运行结果报异常

Exception in thread "main" java.lang.IllegalArgumentException: Cannot reflectively create enum objects

at java.lang.reflect.Constructor.newInstance(Constructor.java:417)

我们点击进去查看一下417行的代码

if ((clazz.getModifiers() & Modifier.ENUM) != 0)

throw new IllegalArgumentException("Cannot reflectively create enum objects");

ConstructorAccessor ca = constructorAccessor;

从这里我们可以看到jdk底层就为我们对反射进行处理了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值