java反射破坏单例模式
来源:互联网 发布:郑州大学软件学院算211 编辑:程序博客网 时间:2024/06/05 05:49
一、 Java中的反射技术可以获取类的所有方法、成员变量、还能访问private的构造方法,这样一来,单例模式中用的私有构造函数被调用就会产生多个实例,编写代码测试一下。
- package test;
- import java.lang.reflect.Constructor;
- public class SingetonTest {
- private static SingetonTest singleton = null;
- private int s = 0;
- // 构造方法是私有的
- private SingetonTest(){}
- // 同步的获取实例方法
- public static synchronized SingetonTest getInstance(){
- // 懒汉模式的单例方法
- if(null == singleton){
- singleton = new SingetonTest();
- }
- return singleton;
- }
- public int getS() {
- return s;
- }
- public void setS(int s) {
- this.s = s;
- }
- /**
- * @param args
- */
- public static void main(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次被调用时抛出异常!修改构造方法如下:
- private static boolean flag = false;
- // 构造方法是私有的
- private SingetonTest(){
- if(flag){
- flag = !flag;
- }
- else{
- try {
- throw new Exception("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
- java反射技术破坏单例模式
- java反射技术-----破坏单例模式
- java反射破坏单例模式
- 反射如何破坏单例模式
- 反射如何破坏单例模式
- 反射如何破坏单例模式
- 序列化 反射破坏单例模式
- 破坏java 单例模式
- java单例模式详解完美实现(包括反射破坏的防止和线程安全)
- 破坏单例模式
- 使用反射破坏和管理单例模式
- 反射 序列化 克隆对单例模式的破坏
- 单例设计模式及反射机制破坏
- 如何破坏单例模式?
- 利用JAVA反射机制破坏单例机制,生成非单例对象
- 让我们来破坏单例模式
- 单例设计模式之破坏
- 单例设计模式之破坏
- 小程序api开发官方开发文档
- ZooKeeper Distributed模式部署
- zoj 2996 (1+x)^n
- ROS(Robot Operating System)开发经验分享-开发工具
- activeMQ 在ssm中的使用-版本 5.14.4
- java反射破坏单例模式
- 剑指offer--二维数组中的查找
- 微信公众号自动化遇到的问题
- EasyUI datagrid获取数据问题
- 心理与自我生活 2
- body 标签禁止横纵滚动条
- servlet实现验证码
- c3p0参数解释
- 1<<i 和 if(i&(1<<j))的用法