java反射--Field用法实践

背景

在工作中,经常需要对特定对象转换成我想要的JSON对象,为了实现通用性想到用反射去实现这个过程。java反射中可用的方法有很多,如Class (反射的入口)Method (成员方法)Field (成员变量),而我想要实现的功能使用Field即可实现。

用法

Field是什么

Field是一个类,位于java.lang.reflect包下。在Java反射中Field类描述的是类的属性信息,功能包括:

  • 获取当前对象的成员变量的类型
  • 对成员变量重新设值

如何使用Field

如何获取Field类对象

一共有4种方法:

  • Class.getFields(): 获取类中public类型的属性,返回一个包含某些 Field 对象的数组,该数组包含此 Class 对象所表示的类或接口的所有可访问公共字段
  • getDeclaredFields(): 获取类中所有的属性(public、protected、default、private),但不包括继承的属性,返回 Field 对象的一个数组
  • getField(String name): 获取类特定的方法,name参数指定了属性的名称
  • getDeclaredField(String name): 获取类特定的方法,name参数指定了属性的名称

Field 类对象常用方法

  • 获取变量的类型:

    • Field.getType():返回这个变量的类型
    • Field.getGenericType():如果当前属性有签名属性类型就返回,否则就返回 Field.getType()
    • isEnumConstant() : 判断这个属性是否是枚举类
  • 获取成员变量的修饰符
    • Field.getModifiers()  以整数形式返回由此 Field 对象表示的字段的 Java 语言修饰符
  • 获取和修改成员变量的值

    • getName() : 获取属性的名字

    • get(Object obj) 返回指定对象obj上此 Field 表示的字段的值

    • set(Object obj, Object value) 将指定对象变量上此 Field 对象表示的字段设置为指定的新值

实践

以工作中使用的代码为举例:

//入参:request为原类型的对象,Sring[]为我想从request中保留的字段,我想要返回的类型为JSONObject
public static JSONObject convertJson(Object request, String[] arr) {
    try {
        JSONObject result = new JSONObject();
        if (StringUtils.isNotBlank(request.toString())) {
            //第一步:获取操作类
            Class clazz = request.getClass();
            //第二步:获取此类的所有的公共(public)的字段,返回 Field 对象的一个数组
            Field[] fields = clazz.getFields();
            for (Field field : fields) {
                //第三步:获取字段的名称
                String fieldValue = field.getName();
                if(ArrayUtils.contains(arr,fieldValue)){
                    //第四步:将字段名称和值进行存储
                    result.put(fieldValue,field.get(request));
                }
            }
        }
        return result;
    } catch (Exception ex) {
        logger.error(ex.getMessage());
        return null;
    }
}

常见错误

  • set(Object obj, Object value) 时,新value和原value的类型不一致导致,如下:无法转换类型导致的 java.lang.IllegalArgumentException(注意:反射获取或者修改一个变量的值时,编译器不会进行自动装/拆箱,所以int 和Integer需手动修改
  • set(Object obj, Object value) 时,修改 final类型的变量导致的 IllegalAccessException。由于 Field 继承自 AccessibleObject , 我们可以使用 AccessibleObject.setAccessible() 方法告诉安全机制,这个变量可以访问即可解决,如field.setAccessible(true)。
  • getField(String name) 或getFields() 获取非 public 的变量,编译器会报 java.lang.NoSuchFieldException 错。

 

 

  • 41
    点赞
  • 158
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值