Java用反射获取与设置成员变量的值

本文介绍了如何使用Java反射机制获取和设置带有private和static修饰符的成员变量的值。通过Class.forName加载类,使用getDeclaredFields获取所有字段,setAccessible(true)解除访问限制,然后通过getName和get方法获取变量值。同样,设置值时使用getDeclaredField和set方法。虽然反射提供了灵活性,但应注意其可能导致封装性的破坏和性能下降,应谨慎使用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

我们在编程的过程中经常会涉及到数据的存取,很多时候我们需要从另一个类中获取数据,而这些类之间可能还没有任何的联系。对于这种情况,就可以用反射来解决。JAVA语言的反射机制在运行状态中,对于任意一个类,都能够获取到这个类的所有属性和方法,对于任意一个对象,都能够调用它的任意一个方法和属性,包括私有的方法和属性。

 

在这个名叫Data的类里面准备了四个变量,并且都已经赋上了值。同时又使用了private和static修饰符进行修饰,所以这四个变量是静态且私有的。

 

在Getdata类中,需要利用反射机制从Data类中获取到那四个对象的值。首先需要使用Class.forName(className)方法加载Data类,加载完类之后就用ClssName.getDeclaredFields()方法来获取该类所声明的所有字段,该方法的返回类型是Field[]。接着用foreach遍历Field[]数组,遍历时用setAccessible(true)来设置允许访问的权限,只有设置了setAccessible为true才可以获取到private修饰的对象。最后使用getName()方法获取该变量的名字,再将获取到的名字放到get()方法来通过名字获取该对象的值。这时候就已经把Data类里面变量的值获取到了,打印到控制台的效果如下图所示。

 

上面是用反射机制来进行值的获取,对应的就会有用反射机制来对值的设置。

用反射来设置成员变量的值跟获取值时一样,需要用Class.forName(className)获取到成员变量所在的类或是接口,然后用ClssName.getDeclaredField(String name)来获取到指定的对象。再用setAccessible(true)来设置允许访问的权限。最后一步就是设置值,用set(Object obj, Object value)方法给成员变量赋值,set方法需要设置两个参数分别是对象与值。到这里就已经完成了用反射机制来对值的设置,控制台打印输出的值就是设置的那个值。

 

通过上面的代码可以知道,通过反射,该类对我们来说是完全透明的,想要获取类里面的任何东西都可以。但是使用反射机制会打破类或是接口的封装性,从而使得java对象属性的不安全。反射还包括了一些动态类型,所以JVM无法对这些代码进行优化。因此,反射操作的效率要比非反射操作低得多。应该避免在经常被执行的代码或对性能要求很高的程序中使用反射。

### 使用Java反射机制获取类的成员变量Java中,通过`java.lang.reflect.Field`类可以访问并操作对象的字段。为了获取特定实例中的字段,需先获得该字段对应的`Field`对象,再调用其`get(Object obj)`方法传入目标对象。 对于公共字段而言,可以直接利用`Class.getFields()`来检索所有可访问(即public修饰符定义)的字段列表[^1]: ```java // 获取Bird类的所有公共字段 Class<?> birdClass = Class.forName("com.chimo.reflection.Bird"); Field[] fields = birdClass.getFields(); for (Field field : fields) { System.out.println(field.getName()); } ``` 然而,在实际开发过程中更常见的是处理私有或其他非公开级别的字段。此时应采用`Class.getDeclaredFields()`代替,并设置字段为可访问状态以便读取或修改其[^3]: ```java import java.lang.reflect.Field; public class ReflectionExample { static class Point { private int x; private int y; public Point(int x, int y){ this.x=x; this.y=y; } } public static void main(String args[]) throws Exception{ // 创建Point实例 Object pointInstance = new Point(10, 20); // 获得Point.class Class<?> clazz = pointInstance.getClass(); // 遍历所有声明的字段 Field[] declaredFields = clazz.getDeclaredFields(); for(Field f : declaredFields){ // 设置字段为可访问 f.setAccessible(true); // 打印字段名及其对应于pointInstance上的 String fieldName = f.getName(); Object fieldValue = f.get(pointInstance); System.out.printf("%s field value: %s\n", fieldName, fieldValue.toString()); } } } ``` 上述代码展示了如何遍历指定类型的全部字段,并打印出给定对象上这些字段的具体数得注意的是,这里使用了`setAccessible(true)`绕过了Java的语言级安全性检查,允许程序访问即使是private修饰的成员变量[^4]。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值