[01][01][04][01] setAccessible方法
2020-10-16 21:51
1011 查看
1. 背景
在测试枚举类型实现单例模式能抵抗反射机制破解的代码中,看constructor.setAccessible(true)代码,不明白其用途
2. setAccessible方法详解
setAccessible并不是在Field中的,而是在AccessibleObject中,AccessibleObject类是Field(字段),Method(方法),Constructor(构造器)类的基类,它提供反射对象绕过Java语言权限控制检查的权限
public static void setAccessible(AccessibleObject[] array, boolean flag) throws SecurityException { SecurityManager sm = System.getSecurityManager(); if (sm != null) sm.checkPermission(ACCESS_PERMISSION); for (int i = 0; i < array.length; i++) { setAccessible0(array[i], flag); } } public void setAccessible(boolean flag) throws SecurityException { SecurityManager sm = System.getSecurityManager(); if (sm != null) sm.checkPermission(ACCESS_PERMISSION); setAccessible0(this, flag); } private static void setAccessible0(AccessibleObject obj, boolean flag) throws SecurityException { if (obj instanceof Constructor && flag == true) { Constructor<?> c = (Constructor<?>)obj; if (c.getDeclaringClass() == Class.class) { throw new SecurityException("Cannot make a java.lang.Class" + " constructor accessible"); } } obj.override = flag; }
setAccessible(AccessibleObject[] array, boolean flag)第一个参数array ,就是要设置flag标志位的Field/Method/Constructor对象的数组,第二个参数flag,将array数组的所有Field/Method/Constructor对象设置为flag标识符的新值
3. setAccessible方法使用
在测试了中方别对私有构造方法,私有方法,私有字段设置不检验权限
访问权限类
@Data @AllArgsConstructor
@NoArgsConstructor
public class User {
private Long id;
private String name;
private Integer age;
private Double score;
private String testMethod(){
return "abcd";
}
}测试类
public class SetAccessibleTest { public static void main(String[] args) {
try {
Class<?> clazz = User.class;
Constructor constructor = clazz.getDeclaredConstructor(null);
// 私有构造方法设置不检查权限
constructor.setAccessible(true);
User user = (User) constructor.newInstance();
// 所有私有属性的方法设置不检查权限
Method[] methods = clazz.getDeclaredMethods();
AccessibleObject.setAccessible(methods, true);
// 所有私有属性的字段设置不检查权限
Field[] fields = clazz.getDeclaredFields();
AccessibleObject.setAccessible(fields, true);
fields[0].setLong(user,1L);
} catch (Exception e) {
e.printStackTrace();
}
}
}
由于JDK的安全检查耗时较多,所以通过setAccessible(true)的方式关闭安全检查就可以达到提升反射速度的效果
相关文章推荐
- 01-Scrum 概述 ,02-橄榄球 VS 软件,03-Scrum敏捷方法一分钟扫盲 ,04-Scrum敏捷方法中的工作产品 ,05-Scrum敏捷方法中的角色,06-Scrum过程-创建和维护产品
- 【jQuery原理】01-jQuery的基本结构 02-jQuery入口函数测试 03-apply和call方法 04-jQuery的extend(扩展)方法 05-jQuery监听DOM加载
- 01_反射_04_反射类的main方法
- 04-01递归原理分析_分析方法调用
- Python补充01 序列的方法
- c#基础精华01(强调代码规范,虚方法,抽象方法,接口)
- 马哥笔记08_01~~~08_04
- Day 3 狂神说Java基础笔记(方法01-06,数组01-09,面向对象01-14)
- 01.判断页面加载完成的方法
- 学习笔记(04):C#急速入门-Main方法,语句,块和关键字
- scala 学习笔记(04) OOP(上)主从构造器/私有属性/伴生对象(单例静态类)/apply方法/嵌套类
- 04.Linux CentOS 7编译安装Jenkins的企业应用管理方法
- ios-day11-01(UIWindow的常用方法。makeKeyWindow、makeKeyAndVisible、获取当前应用的主窗口和所有窗口)
- 脱壳_详细_使用的方法_01
- (一)学习JavaScript中的数组方法01
- Python基础01-04
- 【zepto学习笔记01】核心方法$()(补)
- 数字图像处理实验(5):PROJECT 04-01 [Multiple Uses],Two-Dimensional Fast Fourier Transform
- 酒店管理系统_04-Servlet版本-mysql数据库-方法封装修改数据表结构
- HTML5基础04----HTML5属性使用方法