在測試枚舉類型實現單例模式能抵抗反射機制破解的代碼中,看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