通过反射获取并修改class 中的属性值

384 阅读2分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

这篇文章我们来介绍,如何通过反射获取类的属性值,如何修改类的属性值。

我们依旧根据这篇文章中的类结构来完成下面内容的介绍。

获取并修改类中public 属性值

在上述类中,我们一共定了了三个属性值,一个static,一个public,一个private。

这里我们先介绍一下如何操作public 属性,如何获取并修改它。

Class<?> clazz = Student.class;
try {
    Student student = new Student();
    Field field = clazz.getField("age");
    System.out.println("通过反射得到age: " + field.get(student));
    student.age = 20;
    System.out.println("通过反射得到age: " + field.get(student));
    field.set(student, 30);
    System.out.println(student.age);
} catch (Exception e) {
    e.printStackTrace();
}

这里需要说明的是,调用clazz.getField 的时候,需要传入的参数应该是待处理的变量名,这个方法的返回值不是age属性(不是int age),也就是说,直接通过getField 方法是不能不能直接获取和修改值的。

获取并修改类中的private 属性

在Student 类中我们定义个private 属性是name。我们看一下如何获取并修改name。

Class<?> clazz = Student.class;
try{
    Student student = new Student();
    Field field = clazz.getDeclaredField("name");
    field.setAccessible(true);
    System.out.println("the data from reflection: " + field.get(student));
    field.set(student, "Kite");
    System.out.println(student.getName());
}
catch (Exception e){
    e.printStackTrace();
}

对于获取私有属性,流程和获取public 属性差不多,只不过获取公有属性调用的方法时getField,但是获取私有属性方法的时候获取的是getDeclaredField。(注意:这个方法当然也可以用作获取public 属性)

获取并修改类中的静态属性

这里而我们依旧通过例子来看一下,如何获取类中的静态属性,并做修改。

Class<?> clazz = Student.class;
try{
    Field field = clazz.getDeclaredField("maxAge");
    field.setAccessible(true);
    // 由于这里获取的是静态属性,在调用方法的时候就不需要传入特定的实例对象。
    System.out.println("data from reflection: " + field.get(null));
    field.set(null, 250);
    System.out.println("data from reflection: " + field.get(null));
}
catch (Exception e){
    e.printStackTrace();
}

这里需要注意的只有静态属性和非静态属性的区别,使用也不一样。在通过反射获取静态属性的时候,会调用field.get 方法,这个时候不需要传入实例化对象,只需要传入null 就可以了。

通过反射获取类中的所有属性

最后我们来看一下如何获取类中的所有属性。

Class<?> clazz = Student.class;
Field[] declaredFields = clazz.getDeclaredFields();
Student student = new Student();
for (Field declaredField : declaredFields){
    try{
        declaredField.setAccessible(true);
        System.out.println("field is: " + declaredField.getName() + ", field name is: " + declaredField.getType().getName() + ", value is: " + declaredField.get(student));
    }
    catch (Exception e) {
        e.printStackTrace();
    }
}

这里对比上文,我们只有一个需要记忆的地方,就是clazz.getDeclaredFields(); 就可获取类中所有属性。

总结

这篇文章内容比较多,但是相对来说是比较好记忆以及理解的。主要介绍了如何通过反射获取类中的不同类型的变量,同时介绍了通过什么办法可以去修改这些值。读者理应好好理解并记忆一下。