有如下单例模式设计代码:

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破坏单例设计模式的更多相关文章

  1. JAVA之旅(六)——单例设计模式,继承extends,聚集关系,子父类变量关系,super,覆盖

    JAVA之旅(六)--单例设计模式,继承extends,聚集关系,子父类变量关系,super,覆盖 java也越来越深入了,大家加油吧!咱们一步步来 一.单例设计模式 什么是设计模式? JAVA当中有 ...

  2. java笔记之静态修饰附和单例设计模式

     第六天笔记 静态修饰符static: 一.static修饰成员变量: static用来修饰成员变量叫静态成员变量,没有static修饰的成员变量叫非静态成员变量 静态成员的访问方式: (1)   用 ...

  3. java中你确定用对单例了吗?

    作为程序员这样的特殊物种来说,都掌握了一种特殊能力就是编程思想,逻辑比較慎重,可是有时候总会忽略到一些细节,比方我,一直以来总认为Singleton是设计模式里最简单的,不用太在意,然而就是由于这样的 ...

  4. 如何使用双重检查锁定在 Java 中创建线程安全的单例?

    这个 Java 问题也常被问: 什么是线程安全的单例,你怎么创建它.好吧,在Java 5之前的版本, 使用双重检查锁定创建单例 Singleton 时,如果多个线程试图同时创建 Singleton 实 ...

  5. 单例设计模式(Singleton)

    一.单例设计模式介绍 所谓类的单例设计模式,就是采取一定的方法保证在整个的软件系统中,对某个类只能存在一个对象实例, 并且该类只提供一个取得其对象实例的方法(静态方法) 例如:Hibernate的Se ...

  6. JAVA之旅(十四)——静态同步函数的锁是class对象,多线程的单例设计模式,死锁,线程中的通讯以及通讯所带来的安全隐患,等待唤醒机制

    JAVA之旅(十四)--静态同步函数的锁是class对象,多线程的单例设计模式,死锁,线程中的通讯以及通讯所带来的安全隐患,等待唤醒机制 JAVA之旅,一路有你,加油! 一.静态同步函数的锁是clas ...

  7. Java中如果把构造方法也私有化,如何创建对象?Java的单例设计模式——饿汉式和懒汉式区别

    Java的单例模式——饿汉式 package com.swift; //Java单例设计模式——恶汉式 public class SinglePerson { private String name= ...

  8. Java中常用来处理时间的三个类:Date、Calendar、SimpleDateFormate,以及Java中的单例设计模式:懒汉式、饿汉式以及静态内部类式

    (一)java.util.Date类 1.该类有一个long类型的属性:用来存放时间,是用毫秒数的形式表示,开始的日期是从1970年1月1号 00:00:00.    2.该类的很多方法都已经过时,不 ...

  9. 对Java单例设计模式中懒汉式类定义的讨论

    全世界人民都知道单例设计模式中类的定义分为懒汉式和饿汉式两种,然而今天并不是要把它们做横向比较.实际上,不论饿汉式类的代码看起来有多么美轮美奂,在实际开发中它的效率总是不如懒汉式的.然而在笔试和面试中 ...

随机推荐

  1. Map 综述(三):彻头彻尾理解 ConcurrentHashMap

    https://blog.csdn.net/justloveyou_/article/details/72783008

  2. 【大数据之数据仓库】kudu性能测试报告分析

    本文由  网易云发布. 这篇博文主要的内容不是分析说明kudu的性能指标情况,而是分析为什么kudu的scan性能会这么龊!当初对外宣传可是加了各种 逆天黑科技的呀:列独立存储.bloom filte ...

  3. akka开发(一)HelloWorld

    package com.hfi.helloakka; import akka.actor.ActorRef; import akka.actor.Props; import akka.actor.Un ...

  4. day70 csrf简单用法 &Django ContentType

    一. 什么是跨站请求伪造 CSRF def transfer(request): if request.method =='POST': from_ =request.POST.get('from') ...

  5. apache测试网页执行效率

    apache软件下有一个测试网页访问速度的工具ab.exe,位于apache的bin目录下,windows下使用命令行进入bin目录,执行ab.exe -n 10000 -c 10 http://12 ...

  6. How to manage IntelliJ IDEA projects under Version Control Systems

    如何在版本控制系统中管理 IntelliJ IDEA 项目文件 IntelliJ IDEA 设置详细,功能强大.在实际工作中,我们有时会遇到跟同事共享项目文件的情况. 那么,有哪些项目文件应该加入到版 ...

  7. linux 手动释放buff/cache

    为了解决buff/cache占用过多的问题执行以下命令即可 syncecho 1 > /proc/sys/vm/drop_cachesecho 2 > /proc/sys/vm/drop_ ...

  8. (转)Python中集合(set)的基本操作以及一些常见的用法

    原文:http://blog.51cto.com/10616534/1944841 Python除了List.Tuple.Dict等常用数据类型外,还有一种数据类型叫做集合(set),集合的最大特点是 ...

  9. (转)权威支持: 选择正确的 WebSphere 诊断工具

    权威支持: 选择正确的 WebSphere 诊断工具 原文:https://www.ibm.com/developerworks/cn/websphere/techjournal/0807_supau ...

  10. (转) mysql之status和variables区别及用法详解

    原文:http://blog.csdn.net/andyzhaojianhui/article/details/50052117