反射的private属性
-
-
反射的private属性只能某种程度上限制对字段和方法的访问,可以还是可以依靠反射获取,那么为什么要有反射这个属性呢?
- private并不能保证类的字段绝对安全不被访问,事实上并没有真正安全的办法保证你的代码的安全。private的作用在笔者看来更像是一种声明,一种标签。就像把这个字段标上(不常用)之类的标签一样。private字段标记,是OOP(面向对象编程)的一种使用,使用字段后,可以更加方便得实现对代码得操作。例如在idea的方法提示里,并不会出现对private字段、方法的代码提示。
-
-
setAccessible()方法
- Java反射机制提供的setAccessible()方法可以取消Java的权限控制检查,之后可以通过反射来访问和修改类的属性和方法。另外,我们可以启用java.security.manager来判断程序是否具有调用setAccessible()的权限。默认情况下,内核API和扩展目录的代码具有该权限,而类路径或通过URLClassLoader加载的应用程序不拥有此权限。
-
-
应用
- spring的反射也可以反射私有属性和方法。
个人反射应用
- 通过反射获取类字段并校验(包括父类字段)
public static <T>String[] checkString (Object obj, Class<T> clazz){ // Field[] declaredFields = clazz.getDeclaredFields(); String[] result =null; List<Field> declaredFields = new ArrayList<>() ; while (clazz != null) {//当父类为null的时候说明到达了最上层的父类(Object类). declaredFields.addAll(Arrays.asList(clazz .getDeclaredFields())); Class tempClass =clazz.getSuperclass(); //得到父类,然后赋给自己 clazz = tempClass; } try { for (Field field : declaredFields) { //用于获取private成员变量 field.setAccessible(true); //获取字段值 Object o = field.get(obj); //检验是否合法并返回 if(o!=null){ if(!LegalStringUtils.isLegal(String.valueOf(o))){ result = ArrayUtils.addAll(result,LegalStringUtils.getIllegalChars((String)o)); } } } } catch (IllegalAccessException e) { e.printStackTrace(); } return result; }
//校验方法 private final static String REG_CN_EN_NUMBER = "[\\u4e00-\\u9fa5]|[(A-Za-z)|(0-9)]"; private final static String REG_EN_CHAR = ";'\"|\\/?,.<>[]{}()!-=+- @#$%^&*~`"; private final static String REG_CN_CHAR = ";‘“|、/?,。《》【】{}()!-=+——@#¥%……&*~·"; /** * 判断字符串是否合法 * * @param str :待校验字符串 * @return true or false */ public static boolean isLegal(String str) { for (int i = 0; i < str.length(); i++) { String s = String.valueOf(str.charAt(i)); if (!(s.matches(REG_CN_EN_NUMBER) || REG_EN_CHAR.contains(s) || REG_CN_CHAR.contains(s))) { return false; } } return true; } /** * 返回字符中的非法字符合集 * * @param str :待校验字符串 * @return 若字符串合法,返回空数组,否则返回非法字符数组 */ public static String[] getIllegalChars(String str) { String results = ""; for (String s : str.split("")) { if (!(s.matches(REG_CN_EN_NUMBER) || REG_EN_CHAR.contains(s) || REG_EN_CHAR.contains(s))) { if (results.equals("")) { results = s; } else { results += ("," + s); } } } return results.split(","); }