java反射设置属性值的代码 (java反射修改父类属性值)

一、背景

最近又看了下java反射的一些东西,所以简单汇总记录一下.

二、关于java反射

2.1、什么是java反射

① 反射是一种动态获取信息及调用对象的一种机制。

② 对于一个在运行中的java类,我们都可以知道它的所有属性和方法。

③ 对于一个在运行状态中的对象,我们也都能通过反射来调用它的任意方法已经属性的调用及改变

2.2、什么情况下会用到反射

① 一般来说我们在日常开发中直接用到反射的地方不多,它更多用于框架的开发

② 不能明确接口调用的是哪个函数,需要根据传入参数再运行时决定。

③ 不能明确传入函数的参数类型,但是又需要再运行时处理任意对象

2.3、反射给我们提供了那些支持

① Class.forName(String className): 返回给定字符串名称的类或接口的相关类对象

② getDeclaredConstructors():返回一个数组,包含类的公共构造函数

③ getConstructor(Class<?>, paremeterTypes):返回指定反射类的指定入参类型的构造函数

④ getDeclaredMethos():返回一个数组,包含反射类的所有公共、保护、私有、默认方法(不包括继承的方法

⑤ getDeclaredFields():返回一个数组,包含反射类的所有字段属性

⑥ getDeclaredField(String fieldName): 返回反射类指定名称的字段属性

⑦ getMethods(): 返回一个数组,包含反射类的公共方法,包含继承的方法

⑧ getMethod(String name, Class<?>, paremeteraTypes): 返回反射类指定的公共成员方法

PS:更多信息,请参考官方文档。

三、代码示例


    @Data
    public class Person {
    
        private String name;

        private int age;

        public Person(){
            System.out.println("我是默认构造方法,我被调用了!");
        }

        public Person(String name, int age){
            System.out.println("有参构造 --- 姓名为:" + name + " 年龄为:" + age);
        }

    }



    import com.example.easyexcel.model.Person;
    import java.lang.reflect.Constructor;
    import java.lang.reflect.Field;
    import java.lang.reflect.InvocationTargetException;

    public class Test
    {
        public static void main(String args[]) throws IllegalArgumentException, IllegalAccessException, ClassNotFoundException,
             NoSuchMethodException, InvocationTargetException, InstantiationException, NoSuchFieldException {
            System.out.println("通过反射调用类的默认构造方法");
            Class person = Class.forName("com.example.easyexcel.model.Person");
            Constructor constructor = person.getConstructor(null);
            constructor.newInstance(null);

            System.out.println("通过反射调用类的有参构造方法");
            Constructor constructor1 = person.getConstructor(String.class, int.class);
            constructor1.newInstance("XiaoMing", 19);
            System.out.println("======================================");

            Person bean = new Person();
            bean.setName("ZZSS");
            Field[] fields = bean.getClass().getDeclaredFields();
            Field field = bean.getClass().getDeclaredField("name");
            field.setAccessible(true);
            Object objectName = field.get(bean);
            System.out.println("获取指定字段name的值为:" + objectName);
            System.out.println("======================================");

            for(int i = 0;i < fields.length;i++){
                Field fieldTmp = fields[i];
                // 设置属性是可以访问的
                fieldTmp.setAccessible(true);
                // 得到此属性的值
                Object valTmp = fieldTmp.get(bean);
                String type = fieldTmp.getType().toString();
                System.out.println("字段类型为:" + type);
                System.out.println("属性名:" + fieldTmp.getName());
                System.out.println("属性值:" + valTmp);
                System.out.println("======================================");
                // 得到此属性的类型
                if(type.endsWith("String"))
                {
                    // 给属性设值
                    fieldTmp.set(bean,"LFG");
                }
                else if(type.endsWith("int") || type.endsWith("Integer"))
                {
                    // 给属性设值
                    fieldTmp.set(bean,121);
                }
            }

            System.out.println("重新设值后的对象属性为:"+bean.getName()+"  "+bean.getAge());
        }

    }


Java

程序输出如下:

通过反射调用类的默认构造方法

我是默认构造方法,我被调用了!通过反射调用类的有参构造方法有参构造 --- 姓名为:XiaoMing 年龄为:19======================================我是默认构造方法,我被调用了!获取指定字段name的值为:ZZSS======================================字段类型为:class java.lang.String属性名:name属性值:ZZSS======================================字段类型为:int属性名:age属性值:0======================================重新设值后的对象属性为:LFG 121

四、日志模块中部分代码示例


    private void saveSysLog(ProceedingJoinPoint joinPoint, long time) {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();

        SysLogEntity sysLog = new SysLogEntity();
        SysLog syslog = method.getAnnotation(SysLog.class);
        if (syslog != null) {
            // 注解上的描述
            sysLog.setOperation(syslog.value());
        }

        // 请求的方法名
        String className = joinPoint.getTarget().getClass().getName();
        String methodName = signature.getName();
        sysLog.setMethod(className + "." + methodName + "()");

        // 请求的参数
        Object[] args = joinPoint.getArgs();
        try {
            String params = new Gson().toJson(args[0]);
            sysLog.setParams(params);

            。。。
        } catch (Exception e) {

        }

        // 获取request
        HttpServletRequest request = HttpContextUtils.getHttpServletRequest();
        // 设置IP地址
        sysLog.setIp(IPUtils.getIpAddr(request));

        。。。
        sysLogApi.saveLog(sysLog);
    }


Java

PS: 可以参见:Springboot自定义注解日志管理实现