java 防反射_java防止反射破坏单例模式

我们都知道单例模式是为了实现只创建一个实例,但是java 的反射机制可以破坏这种单例模式,这种通过反射来破坏单例的例子网上多的是,我就不列出来了,今天我们来说说怎么防止使用java的反射机制来破坏单例,查了查网上有很多是在单例的类中增加一个boolean类型的flag,然后在构造函数中来改变flag的值,然后再调用构造函数的时候判断这个flag是否已经改变了,这样来防止重复创建对象实例,当看到这种解决办法的时候就觉得这种方法是不严谨的,因为既然可以通过反射来获取构造函数来创建实例了,那么同样可以通过反射来获取到你定义的flag,那么在利用反射调用构造函数之前,先获取到你这个flag,然后将值重置,那么再次调用构造函数就不会受到限制了,那这样实际上就没有起到防止重复创建的效果。于是我使用了自己想出来的如下方法:

public class SingletonClass {

// private static final Boolean flag = Boolean.FALSE;

private static ImmutableBoolean flag = new ImmutableBoolean();

private SingletonClass() {

if (flag.getCount() <= 0) {

synchronized (SingletonClass.class) {

if (flag.getCount() <= 0) {

flag.setCount();

} else {

throw new RuntimeException("正在破坏单例模式1");

}

}

} else {

throw new RuntimeException("正在破坏单例模式2");

}

}

private static SingletonClass singletonClass = null;

public static SingletonClass getInstance() {

if (singletonClass == null) {

synchronized (SingletonClass.class) {

if (singletonClass == null) {

singletonClass = new SingletonClass();

}

}

}

return singletonClass;

}

private static class ImmutableBoolean {

private static int count = 0;

public ImmutableBoolean() {

}

public void setCount() {

synchronized (SingletonClass.class) {

if (count <= 0) {

count ++;

} else {

throw new RuntimeException("");

}

}

}

public int getCount(){

return count;

}

}

}

public class TestClass {

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

SingletonClass s1 = SingletonClass.getInstance();

// System.out.println(s1);

Classc1 = SingletonClass.class;

// s1.new ImmutableBoolean();

// SingletonClass.ImmutableBoolean

// Field[] fields = c1.getDeclaredFields();

// for (Field field : fields) {

// System.out.println(field.getName());

// if ("flag".equals(field.getName())) {

// field.setAccessible(true);

// Class c2 = field.getClass();

// System.out.println(c2.getName());

Class c3 = field.

System.out.println(c3.getName());

field.

field.setBoolean(s1, false);

break;

// }

// }

Constructorconstructor = c1.getDeclaredConstructor();

constructor.setAccessible(true);

SingletonClass s2 = constructor.newInstance();

System.out.println(s1 == s2);

}

}

我定义了一个私有的内部类,然后用这个内部类的属性来作为flag,这样外面的其他类就获取不到这个私有的内部类,也就不能改变它的值了,从而保护了单例的实现。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值