您的位置 首页 java

Java反射—Field类使用

Field作为反射中对应类或对象中的域或者叫做属性的操作类,除了我前一篇文章中的得到名字和类型等,Field的作用不限于此。

  • 关于Field的一些方法:
  • Java反射—Field类使用

    简单案例:

    Java反射—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。

  • 制作一个通用的toString(Object obj)方法
  • 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有任何问题(学习方法,学习效率,如何就业)都可以问我。希望你也能凭自己的努力,成为下一个优秀的程序员!

    Java反射—Field类使用

    文章来源:智云一二三科技

    文章标题:Java反射—Field类使用

    文章地址:https://www.zhihuclub.com/186290.shtml

    关于作者: 智云科技

    热门文章

    网站地图