最新下载
热门教程
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
Java中 Class.getDeclaredField 怎么获取类中直接声明的 private 字段
时间:2026-07-21 09:15:49 编辑:袖梨 来源:一聚教程网
Class.getDeclaredField()仅获取当前类直接声明的字段(不含父类),包括private字段,但需调用setAccessible(true)才能访问;字段名严格区分大小写,不支持继承查找,不存在时抛NoSuchFieldException。
Class.getDeclaredField 可以获取当前类**直接声明**(不包括父类)的任意访问权限字段,包括 private 字段。关键在于它只查本类,且不检查访问控制——但默认不能直接读写,需配合 setAccessible(true)。
只获取本类声明的 private 字段(不继承)
getDeclaredField(String name) 不会向上查找父类或接口中的字段,哪怕父类有同名 private 字段,也只会返回当前类中定义的那个(如果存在)。若字段不存在,抛出 NoSuchFieldException。
- 子类无法通过该方法获取父类的
private字段(即使同名) - 接口中不允许有
private字段(Java 9+ 接口可有private方法,但字段仍是public static final) - 匿名内部类、Lambda 表达式生成的类也可用,但字段名需按编译器生成的实际名称(如
val$x)
必须调用 setAccessible(true) 才能访问 private 字段
获取到 Field 对象后,它的 get() / set() 默认受 Java 访问控制限制。对 private 字段操作前,必须显式绕过检查:
Field field = clazz.getDeclaredField("secret");field.setAccessible(true); // 关键一步Object value = field.get(instance);field.set(instance, newValue);
- 跳过 JVM 的访问检查,不是“破坏封装”,而是反射的合法能力
- 在启用 SecurityManager 的环境中可能被拒绝(现代应用极少启用)
-
setAccessible(true)对同一个Field实例只需调一次,后续操作无需重复
注意字段名必须完全匹配(区分大小写)
Java 字段名严格区分大小写,且不含任何修饰符信息。例如:
立即学习“Java免费学习笔记(深入)”;
- 类中有
private String userName;→ 必须传"userName",不能是"username"或"USERNAME" - IDE 自动生成的字段(如 Lombok 的
@Data)字段名就是代码里写的名称,不是 getter/setter 名 - 编译器生成的合成字段(如枚举的
$VALUES)也可通过此方法获取,但名字需查字节码确认
替代方案:getDeclaredFields() 遍历所有声明字段
如果不知道字段名,或需要批量处理本类所有 private 字段,可用:
Field[] fields = clazz.getDeclaredFields();for (Field f : fields) { if (Modifier.isPrivate(f.getModifiers())) { f.setAccessible(true); // 处理 f }}
-
getDeclaredFields()返回全部字段(public/protected/private/default),不含继承字段 - 用
Modifier.isPrivate(int)判断访问修饰符 - 适合通用工具类(如深拷贝、序列化框架)中自动处理私有成员
相关文章
- 劲乐幻想预约测试时间介绍 劲乐幻想测试时间何时公布 07-28
- Agent Skill 安装前怎么查风险?SkillSpector 使用方法解析 07-28
- 劲乐幻想模式有哪些 劲乐幻想游戏玩法一览介绍 07-28
- 劲乐幻想幻乐新人室怎么玩 幻乐新人室玩法一览 07-28
- 劲乐幻想观棋何人 劲乐幻想观棋角色信息介绍 07-28
- 劲乐幻想尹谷川是谁 劲乐幻想尹谷川角色信息全览 07-28