Java中反射和Unsafe破坏单例设计模式
有如下单例模式设计代码:
class Singleton
{
private String info = "HELLO SHIT"; private static Singleton instance; private Singleton()
{
System.out.println("******实例化对象******");
} public static Singleton getInstance()
{
synchronized (Singleton.class)
{
if (instance == null)
{
instance = new Singleton();
}
}
return instance;
} public void show()
{
System.out.println("www.google.com");
}
}
按照规则,我们只能获取一个实例化的对象,如下面的代码:
public class Hello
{
public static void main(String[] args) throws Exception
{
Singleton instanceA = Singleton.getInstance();
Singleton instanceB = Singleton.getInstance();
System.out.println(instanceA.hashCode());
System.out.println(instanceB.hashCode());
System.out.println(instanceA == instanceB);
}
}
程序输出:
******实例化对象******
685325104
685325104
true Process finished with exit code 0
可以看到instanceA和instanceB完全相同.
下面演示用反射获取单例的构造函数,并且实例化出多个对象:
public class Hello
{
public static void main(String[] args) throws Exception
{
Constructor c = Singleton.class.getDeclaredConstructor();
c.setAccessible(true); Singleton instanceA = (Singleton)c.newInstance();
Singleton instanceB = (Singleton)c.newInstance();
System.out.println(instanceA.hashCode());
System.out.println(instanceB.hashCode());
System.out.println(instanceA == instanceB);
}
}
程序输出:
******实例化对象******
******实例化对象******
685325104
460141958
false Process finished with exit code 0
可以看到,这里调用了两次构造函数,实例化了两个不同的Singleton对象。
除了用反射,我们还可以用Unsafe类实例化多个单例对象,这种方式和反射的区别在于:Unsafe不需要调用构造函数。因为Unsafe是使用C++进行JVM底层控制。代码如下:
public class Hello
{
public static void main(String[] args) throws Exception
{
Field theUnsafeField = Unsafe.class.getDeclaredField("theUnsafe");
theUnsafeField.setAccessible(true);
Unsafe unsafeInstance = (Unsafe)theUnsafeField.get(null);
Singleton instanceA = (Singleton)unsafeInstance.allocateInstance(Singleton.class);
Singleton instanceB = (Singleton)unsafeInstance.allocateInstance(Singleton.class);
System.out.println(instanceA.hashCode());
System.out.println(instanceB.hashCode());
System.out.println(instanceA == instanceB);
}
}
程序输出:
460141958
1163157884
false Process finished with exit code 0
可以发现上面的代码根本没有调用Singleton的构造函数,而是直接生成了两个实例。
其实上面的代码并没有太大意义,只是作为知识点可以加深对反射和单例的理解和印象。
Java中反射和Unsafe破坏单例设计模式的更多相关文章
- JAVA之旅(六)——单例设计模式,继承extends,聚集关系,子父类变量关系,super,覆盖
JAVA之旅(六)--单例设计模式,继承extends,聚集关系,子父类变量关系,super,覆盖 java也越来越深入了,大家加油吧!咱们一步步来 一.单例设计模式 什么是设计模式? JAVA当中有 ...
- java笔记之静态修饰附和单例设计模式
第六天笔记 静态修饰符static: 一.static修饰成员变量: static用来修饰成员变量叫静态成员变量,没有static修饰的成员变量叫非静态成员变量 静态成员的访问方式: (1) 用 ...
- java中你确定用对单例了吗?
作为程序员这样的特殊物种来说,都掌握了一种特殊能力就是编程思想,逻辑比較慎重,可是有时候总会忽略到一些细节,比方我,一直以来总认为Singleton是设计模式里最简单的,不用太在意,然而就是由于这样的 ...
- 如何使用双重检查锁定在 Java 中创建线程安全的单例?
这个 Java 问题也常被问: 什么是线程安全的单例,你怎么创建它.好吧,在Java 5之前的版本, 使用双重检查锁定创建单例 Singleton 时,如果多个线程试图同时创建 Singleton 实 ...
- 单例设计模式(Singleton)
一.单例设计模式介绍 所谓类的单例设计模式,就是采取一定的方法保证在整个的软件系统中,对某个类只能存在一个对象实例, 并且该类只提供一个取得其对象实例的方法(静态方法) 例如:Hibernate的Se ...
- JAVA之旅(十四)——静态同步函数的锁是class对象,多线程的单例设计模式,死锁,线程中的通讯以及通讯所带来的安全隐患,等待唤醒机制
JAVA之旅(十四)--静态同步函数的锁是class对象,多线程的单例设计模式,死锁,线程中的通讯以及通讯所带来的安全隐患,等待唤醒机制 JAVA之旅,一路有你,加油! 一.静态同步函数的锁是clas ...
- Java中如果把构造方法也私有化,如何创建对象?Java的单例设计模式——饿汉式和懒汉式区别
Java的单例模式——饿汉式 package com.swift; //Java单例设计模式——恶汉式 public class SinglePerson { private String name= ...
- Java中常用来处理时间的三个类:Date、Calendar、SimpleDateFormate,以及Java中的单例设计模式:懒汉式、饿汉式以及静态内部类式
(一)java.util.Date类 1.该类有一个long类型的属性:用来存放时间,是用毫秒数的形式表示,开始的日期是从1970年1月1号 00:00:00. 2.该类的很多方法都已经过时,不 ...
- 对Java单例设计模式中懒汉式类定义的讨论
全世界人民都知道单例设计模式中类的定义分为懒汉式和饿汉式两种,然而今天并不是要把它们做横向比较.实际上,不论饿汉式类的代码看起来有多么美轮美奂,在实际开发中它的效率总是不如懒汉式的.然而在笔试和面试中 ...
随机推荐
- 【转】4G18的低成本NA玩法
首先是要再次强调一次,4G18的缸径是76MM,冲程是87.5MM.属于典型的长冲程低转发动机! 这种设计的优点是比较适合市区走停的工作状况,省油. 如果要针对改装方案而言因为这种低转时便可输出大扭矩 ...
- FFMpeg的一些基础配置
一 . CMakeLists.txt文件的使用 1.添加头文件的相对路径 : include_directories(include(这里面就是文件的名字)) 2.设置ffmpeg的库的路径(v7a或 ...
- 奇异值分解(SVD)详解及其应用
参考:https://blog.csdn.net/shenziheng1/article/details/52916278 论文:http://www-users.math.umn.edu/~lerm ...
- Mcode的介绍
开始时进行的Mcode代码积累平台的分析: 登录模块 Login.html登录页面进行用户的登录,把登录好的用户id存到session里面,转到代码模块 Register.html注册页面进行用户的注 ...
- nc,远程传输文件
linux互传文件nc命令 使用nc命令可以很快的在两台主机传递文件,且不需要在同一网段,只要设置好端口即可. 一.安装(CentOS下) yum install -y nc (需要root权限 ...
- 【xsy1162】鬼计之夜 最短路+二进制拆分
套路题(然而我没看题解做不出来) 题目大意:给你一个$n$个点,$m$条有向边的图.图中有$k$个标记点,求距离最近的标记点间距离. 数据范围:$n,m,k≤10^5$. 设$p_i表$示第$i$个标 ...
- 【xsy1156】 树套树(tree) 倍增
题目大意:给你$m$棵由$n$个点构成的全等的树$A$.这$m$棵树之间有$m-1$条边相连,组成了一棵大树. 有$q$组询问,每次询问这棵大树上两点之间的距离. $n,m,q≤10^5$ 这是一道小 ...
- PowerDesigner最基础的使用方法入门学习(转)
PowerDesigner最基础的使用方法入门学习 1:入门级使用PowerDesigner软件创建数据库(直接上图怎么创建,其他的概念知识可自行学习) 我的PowerDesigner版本是16. ...
- XmlDocument 避免XXE
string xml2 = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\&quo ...
- django框架--路由系统
目录 一.路由系统理解 二.路由系统功能划分 三.路由表创建 创建工具 二级路由 路由别名 动态路由及重定向 四.自定义错误页面 五.图示路由系统在框架中的定位 六.路由系统的进阶想法 一.路由系统理 ...