Java反射操作成员变量核心是Field对象:先获取(getField/getDeclaredField)、再调setAccessible(true)解除限制、最后get/set值;需区分public字段与任意声明字段,注意静态/实例字段调用差异及类型匹配,异常须捕获处理。
Java反射中操作成员变量,核心就是围绕
对象展开:先拿到它,再解除限制,最后读或写值。整个流程不依赖编译期可见性,连
字段也能动态访问。
获取Field对象的两种方式
根据字段访问权限和是否继承,选择合适的方法:
只取public字段(含父类继承的)
:用
或
;若字段不存在或非public,会抛
获取任意声明字段(含private/protected,不含继承)
:必须用
或
;这是操作私有属性的唯一入口
必须调用setAccessible(true)
哪怕拿到了
字段的
对象,直接
或
仍会触发
。关键一步是:
这行代码绕过Java语言访问控制检查,仅影响当前
实例,不影响其他反射行为或运行时安全策略。
读取与修改字段值
值操作分三类场景,注意参数差异:
实例字段
:
和
,
必须是非null的对象实例
静态字段
:
和
,第一个参数固定为
类型匹配
:传入值需与字段声明类型兼容,否则抛
;读取后通常需强制转型,如
异常处理不可省略
反射操作字段常见异常有三个,建议统一捕获处理:
:字段名拼错、大小写不符、或该字段根本不存在于目标类中
:忘了调
,或JDK 12+启用了强封装限制(需加启动参数)
:赋值类型不匹配,比如往
字段塞
FieldprivategetField("fieldName")getFields()NoSuchFieldExceptiongetDeclaredField("fieldName")getDeclaredFields()privateFieldget()set()IllegalAccessExceptionfield.setAccessible(true);Fieldfield.get(obj)field.set(obj, newValue)objfield.get(null)field.set(null, newValue)nullIllegalArgumentException(String) field.get(obj)NoSuchFieldExceptionIllegalAccessExceptionsetAccessible(true)IllegalArgumentExceptionintString