Java 反射和泛型

news/2024/5/19 6:39:43 标签: java, 反射, 泛型, 泛型模板

通过反射泛型实例化对象,并给对象中的属性赋值

UserInfo.java

java">package bean;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;

@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class UserInfo {
    private String username;
    private Integer age;
    private String address;
}

GenericTemplateTest.java

实例化对象,并使用三种方式给对象中的属性赋值

java">import bean.UserInfo;
import org.apache.commons.beanutils.BeanUtils;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.HashMap;
import java.util.Map;

/**
 * 泛型模板测试
 */
public class GenericTemplateTest {
    public static void main(String[] args) throws InstantiationException, IllegalAccessException, InvocationTargetException {
        Map<String, Object> valuesMap = new HashMap<>();
        valuesMap.put("id", 1L);
        valuesMap.put("username", "zhangsan");
        valuesMap.put("age", 17);
        valuesMap.put("address", "beijing");

        ReflectionClass<UserInfo> reflectionClass = new ReflectionClass<>();
        UserInfo userInfo = reflectionClass.instanceClass(UserInfo.class);

//        reflectionClass.setFields1(userInfo, UserInfo.class, valuesMap);
//        reflectionClass.setFields2(userInfo, UserInfo.class, valuesMap);
        reflectionClass.setFields3(userInfo, valuesMap);
        System.out.println(userInfo.toString());
    }
}



class ReflectionClass<T> {
    /**
     * 实例化对象
     * @param cls 待实例化对象的类
     */
    public T instanceClass(Class<T> cls) throws InstantiationException, IllegalAccessException {
        T t = cls.newInstance();
        for (Field declaredField : cls.getDeclaredFields()) {
            System.out.println(declaredField.getName());
        }

        System.out.println("--- 方法 ---");
        Method[] methods = cls.getMethods();
        for(Method method:methods){
            System.out.println("方法:" + method.getName());
            Parameter[] parameters = method.getParameters();
            for (Parameter parameter : parameters) {
                System.out.println(parameter.getName() + " --- " + parameter.getType() + " --- " + parameter.getParameterizedType());
            }

            System.out.println("返回值类型:" + method.getReturnType());
        }

        return t;
    }

    /**
     * 给属性赋值,使用 Field.set() 方法给每个属性赋值
     */
    public void setFields1(T t, Class<T> cls, Map<String, Object> valuesMap) throws InvocationTargetException, IllegalAccessException {
        for (Field declaredField : cls.getDeclaredFields()) {
            declaredField.setAccessible(true);
            declaredField.set(t, valuesMap.get(declaredField.getName()));
        }
    }

    /**
     * 给属性赋值,使用 BeanUtils.setProperty() 方法给每个属性赋值
     */
    public void setFields2(T t, Class<T> cls, Map<String, Object> valuesMap) throws InvocationTargetException, IllegalAccessException {
        for (Field declaredField : cls.getDeclaredFields()) {
            BeanUtils.setProperty(t, declaredField.getName(), valuesMap.get(declaredField.getName()));
        }
    }

    /**
     * 给属性赋值,使用 BeanUtils.populate() 给与 map 中对应的属性名称赋值
     */
    public void setFields3(T t, Map<String, Object> valuesMap) throws InvocationTargetException, IllegalAccessException {
        BeanUtils.populate(t, valuesMap);
    }
}

执行后,在 console 输出:

java">username
age
address
--- 方法 ---
方法:equals
arg0 --- class java.lang.Object --- class java.lang.Object
返回值类型:boolean
方法:toString
返回值类型:class java.lang.String
方法:hashCode
返回值类型:int
方法:getAddress
返回值类型:class java.lang.String
方法:setAddress
arg0 --- class java.lang.String --- class java.lang.String
返回值类型:void
方法:getAge
返回值类型:class java.lang.Integer
方法:setAge
arg0 --- class java.lang.Integer --- class java.lang.Integer
返回值类型:void
方法:getUsername
返回值类型:class java.lang.String
方法:setUsername
arg0 --- class java.lang.String --- class java.lang.String
返回值类型:void
方法:wait
返回值类型:void
方法:wait
arg0 --- long --- long
arg1 --- int --- int
返回值类型:void
方法:wait
arg0 --- long --- long
返回值类型:void
方法:getClass
返回值类型:class java.lang.Class
方法:notify
返回值类型:void
方法:notifyAll
返回值类型:void
UserInfo(username=zhangsan, age=17, address=beijing)


http://www.niftyadmin.cn/n/205742.html

相关文章

mq基本梳理 为啥用mq

为什么要用mq&#xff1f; 解耦 异步 削峰填谷 业务—发短信–邮件 高并发有问题 tomcat默认150个链接&#xff0c;业务系统&#xff0c;要1s钟&#xff0c;并发量就是150个链接。并发数150个。 可以做成异步&#xff0c;时间不一定。 业务太大&#xff0c;拒绝请求也不行…

day28 SpringBootWeb(四)事务AOP

目录 事务&AOP 1. 事务管理 1.1 事务回顾 1.2 案例 1.3 Spring事务管理 1.4 事务进阶 2. AOP基础 2.1 记录方法执行耗时 2.2 AOP快速入门 2.3 执行流程 2.4 AOP核心概念 3. AOP进阶 3.1 通知类型 3.2 通知顺序 3.3 切点表达式 3.4 连接点 4. AOP案例 4.1 …

逍遥自在学C语言 | 逻辑运算符

前言 一、人物简介 第一位闪亮登场&#xff0c;有请今后会一直教我们C语言的老师 —— 自在。 第二位上场的是和我们一起学习的小白程序猿 —— 逍遥。 二、构成和表示方式 逻辑运算符是用来比较和操作布尔值的运算符C语言中的逻辑运算符主要有3个&#xff0c;如下表所示 运…

重置mysql数据库密码

1、mysqladmin命令 mysqladmin -u user -h host -p password "newpwd"user&#xff1a;需要修改密码的用户名称&#xff1b; host&#xff1a;需要修改密码的用户主机名&#xff0c;空则默认是localhost&#xff1b; newpwd&#xff1a;设置的新密码&#xff0c;需用…

MATLAB编写黄金分割法

以下是使用MATLAB编写黄金分割法求解f(x)x22xf(x)x^22xf(x)x22x在区间[−3,5][-3,5][−3,5]上的最小值的代码&#xff1a; function [xmin,fmin] goldenSectionMethod(f,a,b,tol) % 黄金分割法求解函数f在区间[a,b]上的最小值 % 输入&#xff1a; % f - 函数句柄&#xff0…

大数据项目实战之数据仓库:电商数据仓库系统——第3章 维度建模理论之事实表

第3章 维度建模理论之事实表 3.1 事实表概述 事实表作为数据仓库维度建模的核心&#xff0c;紧紧围绕着业务过程来设计。其包含与该业务过程有关的维度引用&#xff08;维度表外键&#xff09;以及该业务过程的度量&#xff08;通常是可累加的数字类型字段&#xff09;。 3.…

AR”将会成为“更加日常化的移动设备应用的一部分”吗

目录 1&#xff1a;AR是什么 2&#xff1a;AR给人类带来的贡献 3&#xff1a;人们在生活中可以遇到许多 AR 技术应用 4&#xff1a;AR 技术的未来发展的趋势&#xff1a; 大学主攻VR&#xff0c;从大一就对VR的知识&#xff0c;设备&#xff0c;已经所涉及的知识伴随我的整…

入门前端框架Layui

&#x1f3ed; 作者&#xff1a;哈桑c&#xff08;CSDN平台&#xff09; ⛺️ 专栏&#xff1a;前端自学记录 文章目录文章简介说在前面的话需要具备的基础1、Layui 的介绍2、Layui 的下载和使用3、Layui 示例4、Layuimini layui-vue结语文章简介 本文为大家介绍前端 UI 组件…