栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

反射工具类ReflectionUtils

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

反射工具类ReflectionUtils

1. 什么是反射

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

2. 反射的实现

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

        TextMessage text = new TextMessage();
        Class clazz = text.getClass();

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

Class 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);
}
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1004065.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号