Field作为反射中对应类或对象中的域或者叫做属性的操作类,除了我前一篇文章中的得到名字和类型等,Field的作用不限于此。
简单案例:
package io.ilss.reflection; import Java . lang .annotation.Annotation; import java.lang.reflect.Field; /** * className UserTest * description UserTest * * @author feng * @version 1.0 * @date 2019-01-26 19:12 */ public class UserTest { public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException { User user = new User("ilss", "ilss password"); Class cls = user.getClass(); //获取 username 名字的Field Field usernameField = cls.getDeclaredField("username"); System.out.println(usernameField.toString()); //获取user对象对应的username Object o = getSafe(usernameField, user); System.out.println("The username value of user is " + o); //获取基本数据类型 user.setSex(1); Field sexField = cls.getDeclaredField("sex"); sexField.setAccessible(true); sexField.setInt(user, 2); int sex = sexField.getInt(user); System.out.println("user sex : " + sex); //对user进行修改值 pubic不需要setAccessible Field addressField = cls.getDeclaredField("address"); addressField.set(user, "ilss address"); System.out.println("user address : " + user.getAddress()); } public static Object getSafe(Field field, Object obj) { Object ret = null; try { if (field.isAccessible()) { ret = field.get(obj); } else { field.setAccessible(true); ret = field.get(obj); } } catch (IllegalAccessException e) { e.printStackTrace(); } return ret; } }
需要说的点: setAccessible方法。是Field继承自AccessibleObject类,AccessibleObject是Field、Method、Constuctor类的父类。简单理解意思就是 如果类型是private修饰的,你不可以直接访问,就需要设置访问权限为true.如果是public则不需要设置。 set和get调用的时候都需要确保可以访问,不然如果不能访问抛出IllegalAccessException。
package io.ilss.reflection; import java.lang.reflect.AccessibleObject; import java.lang.reflect.Array; import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.util.ArrayList; /** * className ObjectAnalyzer * description ObjectAnalyzer * * @author feng * @version 1.0 * @date 2019-01-26 19:34 */ public class ObjectAnalyzer { private ArrayList<Object> visited = new ArrayList<>(); public String toString(Object obj) { //无效处理 if (obj == null) { return "null"; } //注意 如果不判断contains可能会出现无限 递归调用 。 if (visited.contains(obj)) { return "..."; } //将已经处理的做记录 visited.add(obj); Class cls = obj.getClass(); //如果为String类型就直接返回 if (cls == String.class) { return (String) obj; } //是否数组 if (cls.isArray()) { //用StringBuilder来 append 字符串 StringBuilder r = new StringBuilder(cls.getComponentType() + "[]{"); //利用relect包的Array操作类来便利 for (int i = 0; i < Array.getLength(obj); i++) { if (i > 0) { r.append(","); } Object val = Array.get(obj, i); // getComponentType() 得到数组对象元素的类型 // isPrimitive()是判断是否是基本数据类型 if (cls.getComponentType().isPrimitive()) { r.append(val); } else { //不是基本数据类型就递归调用。 r.append(toString(val)); } } return r + "}"; } StringBuilder ret = new StringBuilder(cls.getName()); do { ret.append("["); Field[] fields = cls.getDeclaredFields(); //对fields数组的所有访问权限设置为true AccessibleObject.setAccessible(fields, true); for (Field f : fields) { //只对非static参数处理 if (!Modifier.isStatic(f.getModifiers())) { //如果不是第一个就加逗号 if (!ret.toString().endsWith("[")) { ret.append(","); } ret.append(f.getName()).append("="); try { //对field的值进行获取 Class t = f.getType(); Object val = f.get(obj); //基本数据类型就直接append 不是就递归调用 if (t.isPrimitive()) { ret.append(val); } else { ret.append(toString(val)); } } catch (Exception e) { e.printStackTrace(); } } } ret.append("]"); //处理父类 cls = cls.getSuperclass(); } while (cls != null); return ret.toString(); } @Override public String toString() { //利用自己调用toString(this)来实现自己的toString return this.toString(this); } }
注意:
里面有个Array类,是java.lang.reflect包下一个数组操作类。代码里的调用意思都不难理解。就不解释了
- 调用类
package io.ilss.reflection; import java.util.ArrayList; import java.util.List; /** * className ObjectAnalyzerTest * description ObjectAnalyzerTest * * @author feng * @version 1.0 * @date 2019-01-26 19:30 */ public class ObjectAnalyzerTest { public static void main(String[] args) { List<Integer> squares = new ArrayList<>(); for (int i = 0; i < 5; i++) { squares.add(i * i); } System.out.println(new ObjectAnalyzer().toString(squares)); System.out.println(new ObjectAnalyzer().toString()); User[] arr = new User[10]; System.out.println(new ObjectAnalyzer().toString(arr)); User user = new User("ilss", "ilss password"); System.out.println(new ObjectAnalyzer().toString(user)); } }
小编是一个有着5年工作经验的程序员,关于Java,自己有做材料的整合,一个完整学习Java的路线,学习材料和工具。需要的伙伴可以私信我,发送“交流”后就可免费获取。对于学习Java有任何问题(学习方法,学习效率,如何就业)都可以问我。希望你也能凭自己的努力,成为下一个优秀的程序员!