终结者单身——setAccessible(true)
首先看一下“传说”Singleton模式
package go.derek; public class Singleton{ public static int times;
private Singleton(){
//构造器被调用的时候会打印出次数
System.out.println("单例构造器被调用"+(++times)+"两次");
} private final static Singleton instance=new Singleton(); public static Singleton getInstance(){
return instance;
} public void doSomething(){
System.out.println("do something");
} }
以下是測试类主函数:
package go.derek; import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException; public class Test {
public static void main(String[] args) throws NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
//通过单例模式获得单例对象obj1
Singleton obj1=Singleton.getInstance();
//运行一次doSomething方法
obj1.doSomething();
//观察控制台,这次获得的obj2对象跟obj1是同一个单例。没有调用构造器
Singleton obj2=Singleton.getInstance();
obj2.doSomething();
//以下厉害的来了,首先拿到万能的Class对象
Class<Singleton> clazz=Singleton.class;
//然后拿到构造器。使用这种方法私有的构造器也能够拿到
Constructor<Singleton> c=clazz.getDeclaredConstructor();
//设置在使用构造器的时候不运行权限检查
c.setAccessible(true);
//因为没有了权限检查。所以在Singleton类外面也能够创建对象了,然后运行方法
//观察控制台,私有构造器又被调用了一次,单例模式被攻陷了,运行方法成功。 c.newInstance().doSomething();
}
}
执行结果例如以下:
单例构造器被调用1两次
do something
do something
单例构造器被调用2两次
do something
试想一下,假设某个恶意client通过上面的方式。就能够为所欲为了。所以为了避免出现这样的情况,能够再构造器被第二次调用的时候抛出一个异常
package go.derek; public class Singleton{ public static int times;
private Singleton() {
//构造器被调用的时候会打印出次数
System.out.println("单例构造器被调用"+(++times)+"两次");
if(instance!=null){
throw new IllegalArgumentException("单例构造器不能反复使用");
}
} private final static Singleton instance=new Singleton(); public static Singleton getInstance(){
return instance;
} public void doSomething(){
System.out.println("do something");
} }
执行结果例如以下:
单例构造器被调用1两次
do something
do something
单例构造器被调用2两次
Exception in thread "main" java.lang.reflect.InvocationTargetException
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:526)
at go.derek.Test.main(Test.java:24)
Caused by: java.lang.IllegalArgumentException: 单例构造器不能反复使用
at go.derek.Singleton.<init>(Singleton.java:10)
... 5 more
目标实现~
版权声明:本文博客原创文章,博客,未经同意,不得转载。
终结者单身——setAccessible(true)的更多相关文章
- Java 反射 getDeclareFields getModifiers setAccessible(true)
示例代码: public static Map<String, Object> dtoToMap(Object obj, String pre, String las ...
- field.setAccessible(true) 简介
今天查看别人写的代码时,发现这样一句代码,顿时来了兴趣. 需要注意setAccessible 并不是在Field中的,而是在AccessibleObject中. 下面是AccessibleObject ...
- 提高java反射速度的方法method.setAccessible(true)
转载:http://huoyanyanyi10.iteye.com/blog/1317614 提高java反射速度的方法method.setAccessible(true) package com.c ...
- [转载] 在java中为什么变量1000 = 1000 返回false,但是100=100返回true?
ps:题目的意思是指定义相同内容的不同变量之间的==比较.如果直接比较(100 == 100)的结果是true. 运行以下代码: Integer a = 1000, b = 1000; System. ...
- Java中1000==1000为false而100==100为true
public static void main(String[] args) { int z1 = 0; int z2 = 0; System.out.println(z1==z2);//TRUE I ...
- Java 反射 调用私有域和方法(setAccessible)
Java 反射 调用私有域和方法(setAccessible) @author ixenos AccessibleObject类 Method.Field和Constructor类共同继承了Acces ...
- 为什么Java 两个Integer 中1000==1000为false而100==100为true?
详见:http://blog.yemou.net/article/query/info/tytfjhfascvhzxcyt346 这是一个挺有意思的讨论话题. 如果你运行下面的代码 1 2 3 4 I ...
- 反射setAccessible()方法
java代码中,常常将一个类的成员变量置为private 在类的外面获取此类的私有成员变量的value时,需要注意: 测试类: public class AccessibleTest { privat ...
- 奇怪的Java题:为什么1000 == 1000返回为False,而100 == 100会返回为True?
如果你运行如下代码: 1 2 3 4 Integer a = 1000, b = 1000; System.out.println(a == b);//1 Integer c = 100, d = ...
随机推荐
- hdu 4925 贪心 自己从小到大做数据找方法规律
http://acm.hdu.edu.cn/showproblem.php?pid=4925 自己逐个做数据找规律.提供下我的找的: 1 2 1 3 2 2 2 3 3 3 然后发现这种矩阵是最优的: ...
- HDU 2544 最短路 SPFA 邻接表 模板
Problem Description 在每年的校赛里,全部进入决赛的同学都会获得一件非常美丽的t-shirt.可是每当我们的工作人员把上百件的衣服从商店运回到赛场的时候,却是非常累的!所以如今他们想 ...
- Microsoft Visio 2010 怎样把直线,虚线与箭头之间切换
我也是第一次接触这个东西,感慨是把箭头变成直线都搞了半天没搞出来,上网搜页没结果,一次偶然我会了,真是老天爷眷顾我,如今把方法给大家分享,欢迎大家不吝赐教. 直线变箭头: 刚開始是直线: 接着选中直线 ...
- JAVA 读取图片储存至本地
需求:serlvet经过处理通过报表工具返回一张报表图(柱状图 折线图). 现在需要把这个图存储到本地 以便随时查看 // 构造URL URL url = new URL(endStr); // 打开 ...
- Codeforces 191 C Fools and Roads (树链拆分)
主题链接~~> 做题情绪:做了HDU 5044后就感觉非常easy了. 解题思路: 先树链剖分一下,把树剖分成链,由于最后全是询问,so~能够线性操作.经过树链剖分后,就会形成很多链,可是每条边 ...
- pygame系列_mouse鼠标事件
pygame.mouse提供了一些方法获取鼠标设备当前的状态 ''' pygame.mouse.get_pressed - get the state of the mouse buttons get ...
- C# WPF Datagrid的筛选
public static void SearchResult(DataGrid dg,string condition) { #region string code = string.Empty; ...
- app服务器
http://heipark.iteye.com/blog/1847421http://heipark.iteye.com/blog/1847421http://wenku.baidu.com/vie ...
- windows phone (16) UI变换 下
原文:windows phone (16) UI变换 下 上一篇中说到四个变换类,都是比较简单的,这里要说到四个变换类,分别为: MatrixTransfrom矩阵变换,一句标准矩阵表示的变换 Tra ...
- python学习笔记之三:字典,当索引不好用时
字典是python中唯一内建的映射类型.字典中的值并没有特殊的顺序,但是都存储在一个特定的键(key)里.键可以是数字,字符串甚至是元组. 1. 创建和使用字典 字典可以通过下面的方式创建: phon ...