反射工具类ReflectionUtils

1. 什么是反射

JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
通俗点讲,反射就是把java类中的各种成分映射成一个个的Java对象
例如:类的class声明(class对象),变量(field),方法(method)等等信息,利用反射技术可以对一个类进行解剖,动态获取信息进行处理。

2. 反射的实现

1、获取Class对象的三种方式
1.1 Object ——> getClass();

        TextMessage text = new TextMessage();
        Class<? extends TextMessage> clazz = text.getClass();

1.2 任何数据类型(包括基本数据类型)都有一个“静态”的class属性

Class<TextMessage> clazz = TextMessage.class;

1.3 通过Class类的静态方法:forName(String className)(常用)

Class clazz = Class.forName("com.demo.TextMessage");

3. ReflectionUtils常见方法使用

//通过属性名称name和类型type,从clazz获取field
public static Field findField(Class clazz, String name, Class type) 
//通过属性名称name,从clazz获取field
public static Field findField(Class clazz, String name)
//给对应target对象的field赋值value
public static void setField(Field field, Object target, Object value) 
//根据属性字段field和对象target,获取的对象中字段的值 
public static Object getField(Field field, Object target)
//根据类,方法名称和参数类型查找方法 
public static Method findMethod(Class clazz, String name) 
//根据类,方法名称和参数类型查找方法
public static Method findMethod(Class clazz, String name, Class[] paramTypes) 
//调用target对象的方法,无入参
public static Object invokeMethod(Method method, Object target)
//调用target对象的方法,入参为args
public static Object invokeMethod(Method method, Object target, Object[] args)
//判断属性是否包含特定修饰符
public static boolean isPublicStaticFinal(Field field) 
//让属性可以访问,主要针对私有属性
public static void makeAccessible(Field field) 

4. ReflectionUtils实现源码demo分析

findField方法根据类型,字段名称和字段类型查询一个字段,主要实现就是遍历的向父类获取clazz所有的field,然后进行name和type的匹配,进而找到对应的field。

public static Field findField(Class<?> clazz, String name, Class<?> type) {
    Class<?> searchType = clazz;
    while (Object.class != searchType && searchType != null) {
        Field[] fields = getDeclaredFields(searchType);
        for (Field field : fields) {
            if ((name == null || name.equals(field.getName())) &&
                    (type == null || type.equals(field.getType()))) {
                return field;
            }
        }
        searchType = searchType.getSuperclass();
    }
    return null;
}

private static Field[] getDeclaredFields(Class<?> clazz) {
//对类型和字段做了缓存,保存到了declaredFieldsCache中
    Field[] result = declaredFieldsCache.get(clazz);
    if (result == null) {
        result = clazz.getDeclaredFields();
        declaredFieldsCache.put(clazz, (result.length == 0 ? NO_FIELDS : result));
    }
    return result;

5. ReflectionUtils使用场景

最实用的场景就是,当一个接口或者方法针对不同的场景,需要取不同的对象,进行不同的处理。比如发送消息的接口,针对不同的消息类型,可能要处理的数据不一样,有文本消息,有图片消息,有短链,或者菜单栏消息等等。

//通过定义的type字段作区分
//然后找到type对应的属性字段
//找到对应的field对象
Field field = ReflectionUtils.findField(req.getClass(), typeEnum.getField());
//获取数据并赋值
if (Objects.nonNull(field)) {
//设置为可访问
ReflectionUtils.makeAccessible(field);
//根据field的type解析对应的值
Object msgBody = jsonUtils.readValue(bodyStr, field.getType());
//给对象对应的属性字段赋值
ReflectionUtils.setField(field, req, msgBody);
}
  • 1
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java 反射工具类 ReflectUtils 是一个提供了便捷的反射操作方法的工具类。它封装了 Java 反射 API 的一些常用功能,使得开发者能够更加方便地使用反射进行类、方法、字段的操作。 ReflectUtils 提供了以下几个方法: 1. getTypeArguments:通过反射获取指定类的泛型类型参数。可以通过该方法来获取泛型类型的具体参数类型,方便在运行时进行类型判断和操作。 2. invokeGetter:通过反射调用指定对象的指定字段的 getter 方法。在无法直接访问字段或需要动态调用字段的 getter 方法时,可以使用该方法。 3. invokeSetter:通过反射调用指定对象的指定字段的 setter 方法。在无法直接访问字段或需要动态调用字段的 setter 方法时,可以使用该方法。 4. getFieldValue:通过反射获取指定对象的指定字段的值。在无法直接访问字段时,可以使用该方法获取字段的值。 5. setFieldValue:通过反射设置指定对象的指定字段的值。在无法直接访问字段时,可以使用该方法设置字段的值。 6. getField:通过反射获取指定类的指定字段。可以用于获取字段的修饰符、类型等信息。 7. getMethod:通过反射获取指定类的指定方法。可以用于获取方法的修饰符、返回值类型、参数类型等信息。 ReflectUtils 的使用能够简化反射操作的代码,提高开发效率,但也需要注意合理使用,避免引入不必要的复杂性。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值