在测试枚举类型实现单例模式能抵抗反射机制破解的代码中,看constructor.setAccessible(true)代码,不明白其用途java
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标识符的新值安全
在测试了中方别对私有构造方法,私有方法,私有字段设置不检验权限ide
访问权限类测试
@Data @AllArgsConstructor
@NoArgsConstructor
public class User {
private Long id;
private String name;
private Integer age;
private Double score;
private String testMethod(){
return "abcd";
}
}
测试类this
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)的方式关闭安全检查就能够达到提高反射速度的效果code