2026/8/16 16:47:12

496. Java 反射 - 使用反射访问 Record 字段

496. Java 反射 - 使用反射访问 Record 字段 文章目录496. Java 反射 - 使用反射访问 Record 字段1. 背景说明2. 示例获取字段信息3. 示例读取字段值4. 示例尝试修改字段值5. 总结496. Java 反射 - 使用反射访问 Record 字段1. 背景说明在普通类中字段field既可以通过Class.getDeclaredFields()获取也能在必要时修改配合setAccessible(true)绕过可见性检查。但Record 与普通类不同它的字段是private final的private不可直接在类外访问。final一旦赋值在构造函数或 canonical constructor 中就不允许再修改。这种特性保证了Record 的不可变性immutability即对象创建后其状态无法再被更改。2. 示例获取字段信息假设我们有一个PointrecordpublicrecordPoint(intx,inty){}我们可以通过反射获取它的字段Class?cPoint.class;Field[]fieldsc.getDeclaredFields();for(Fieldfield:fields){System.out.println(field field);}输出结果fieldprivatefinalintorg.devjava.Point.x fieldprivatefinalintorg.devjava.Point.y✅ 说明可以看到x和y字段都被编译器标记为private final。3. 示例读取字段值即使是private字段也可以通过反射读取值PointpnewPoint(1,2);FieldxFieldp.getClass().getDeclaredField(x);xField.setAccessible(true);// 绕过 private 限制intx(int)xField.get(p);System.out.println(x x);输出结果x1说明我们仍然能够读取Record字段的值。优化写法xField.getInt(p)可以避免装箱/拆箱开销。4. 示例尝试修改字段值如果你尝试修改字段值PointpnewPoint(1,2);FieldxFieldp.getClass().getDeclaredField(x);xField.setAccessible(true);xField.setInt(p,0);System.out.println(p p);运行结果会抛出异常Exceptionin threadmainjava.lang.IllegalAccessException:Cannot setfinalintfieldorg.devjava.Point.xto(int)0✅ 说明即使设置了setAccessible(true)JVM 依然会阻止修改final字段。这是 Record 的特殊约束目的是保证不可变性。5. 总结获取字段使用Class.getDeclaredFields()。读取值可以通过Field.get()或Field.getInt()。修改值不允许即使使用反射也会抛出IllegalAccessException。意义这是 Record 语义设计的一部分保证了对象在创建后不变不可变对象更安全尤其适用于多线程场景。