JAVA反射破单例模式_java反射技术-----破坏单例模式

前天面试遇到一面试官问我的,让我写一个单例模式,然后就问我通过什么方法能够获得更多的单例对象,由于很久没用过反射,当时我忘记了反射原理的使用,思考的方向不对。今天上网搜一下

一、 Java中的反射技术可以获取类的所有方法、成员变量、还能访问private的构造方法,这样一来,单例模式中用的私有构造函数被调用就会产生多个实例,编写代码测试一下。

packagetest;

importjava.lang.reflect.Constructor;

publicclassSingetonTest {

privatestaticSingetonTest singleton =null;

privateints =0;

// 构造方法是私有的

privateSingetonTest(){}

// 同步的获取实例方法

publicstaticsynchronizedSingetonTest getInstance(){

// 懒汉模式的单例方法

if(null== singleton){

singleton = newSingetonTest();

}

returnsingleton;

}

publicintgetS() {

returns;

}

publicvoidsetS(ints) {

this.s = s;

}

/**

* @param args

*/

publicstaticvoidmain(String[] args) {

try{

Constructor con = SingetonTest.class.getDeclaredConstructor();

con.setAccessible(true);

// 通过反射获取实例

SingetonTest singetonTest1 = (SingetonTest)con.newInstance();

SingetonTest singetonTest2 = (SingetonTest)con.newInstance();

// 常规方法获取实例

SingetonTest singetonTest3 = SingetonTest.getInstance();

SingetonTest singetonTest4 = SingetonTest.getInstance();

// 测试输出

System.out.println("singetonTest1.equals(singetonTest2) :"+  singetonTest1.equals(singetonTest2));

System.out.println("singetonTest3.equals(singetonTest4) :"+  singetonTest3.equals(singetonTest4));

System.out.println("singetonTest1.equals(singetonTest3) :"+  singetonTest1.equals(singetonTest3));

singetonTest1.setS(1);

singetonTest2.setS(2);

singetonTest3.setS(3);

singetonTest4.setS(4);

System.out.println("1:"+ singetonTest1.getS() +"  2:"+ singetonTest2.getS()+"  3:"+ singetonTest3.getS()+"  4:"+ singetonTest4.getS());

} catch(Exception e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

}

测试结果:

singetonTest1.equals(singetonTest2) :false

singetonTest3.equals(singetonTest4) :true

singetonTest1.equals(singetonTest3) :false

1:1  2:2  3:4  4:4

通过反射技术生成的两个实例不同,通过常规方法获取的两个实例相同(即同一个实例,单例)。

二、防止反射破坏单例模式,构造函数调用时进行处理,当构造函数第2次被调用时抛出异常!修改构造方法如下:

privatestaticbooleanflag =false;

// 构造方法是私有的

privateSingetonTest(){

if(flag){

flag = !flag;

}

else{

try{

thrownewException("duplicate instance create error!"+ SingetonTest.class.getName());

} catch(Exception e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

}

三、一些思考

1)单例模式是为了保证一个类只有一个实例,整个系统只能有自己创建的一个实例。应用在数据库连接或单个队列处理等问题。

2)单例模式构造,懒汉模式以时间换空间(用的时候才生产实例,每次都判断);懒汉模式以空间换时间,直接创建实例,以后不用判断直接用。

3)懒汉模式线程安全问题,获取实例的方法要加上synchronized进行同步。

4)java的反射技术不要用于实例创建,反射主要用于Spring的IOC, Hibernate和白盒测试。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值