当前位置: 首页 > news >正文

Java反射的Field

Java 反射获取 Field 的 4 种方法总结

1.getField():只能获取public,包括继承父类的
2.getDeclaredFiled():可以获取类声明的任何字段,但是不包括父类继承的
3.getFields():返回所有public字段,包括父类继承的
4.getDeclaredFields:返回声明的所有字段,不包括从父类继承的

常见两个异常

NoSuchFieldException
IllegalAccessException

权限与setAccessible(true)

在这里插入图片描述

示例

对于User类:
public的字段location, private字段id, default字段age, protected字段salary

package reflect.bean;/*** @author * @version 1.0* @description: TODO* @date 2025/7/30 11:40*/
public class User {public String location;private String id;int age;String name;protected  double salary;public User() {}public User(int age, String name) {this.age = age;this.name = name;}public User(String id, int age, String name) {this.id = id;this.age = age;this.name = name;}private int getNum(){return 1;}public int getA(){return 3;}int getB(){return 4;}public static void utils(){System.out.println("test");}@Overridepublic String toString() {return "User{" +"location='" + location + '\'' +", id='" + id + '\'' +", age=" + age +", name='" + name + '\'' +", salary=" + salary +'}';}
}

测试getField方法

访问public字段可以,其他字段不行,会报错

 // 只能获取 public 修饰的字段(包括从父类继承的)@Testpublic void testGetField() throws NoSuchFieldException{Field location = User.class.getField("location");System.out.println(location);//        Field age = User.class.getField("age");
//        System.out.println(age);}

测试getDeclaredField

// 可以获取类中声明的任何字段(包括 private、protected、public)//不能获取从父类继承的字段@Testpublic void testGetDeclaredField()throws NoSuchFieldException{Field age = User.class.getDeclaredField("age");System.out.println(age);}

测试getFields()

// 返回所有 public 字段(包括从父类继承的)@Testpublic void testGetFields() throws NoSuchFieldException{Field[] fields = User.class.getFields();for(Field field:fields){System.out.println(field);}}

测试getDeclaredFields()

//    返回类中声明的所有字段(包括 private、protected、public)
//
//    不包含从父类继承的字段@Testpublic void testGetDeclaredFields() throws NoSuchFieldException{Field[] declaredFields = User.class.getDeclaredFields();for(Field field:declaredFields){System.out.println(field);}}

测试setAccessible

如果在User同一个包下:访问default和protected字段都行

package reflect.bean;import java.lang.reflect.Field;/*** @author * @version 1.0* @description: TODO* @date 2025/8/4 20:11*/
public class Test {public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {Field location = User.class.getField("location");User user = new User();location.set(user,"巢湖市区");System.out.println(user);Field id = User.class.getDeclaredField("id");id.setAccessible(true);id.set(user,"222");System.out.println(user);Field age = User.class.getDeclaredField("age");age.set(user,11);System.out.println(user);Field salary = User.class.getDeclaredField("salary");salary.set(user,19992.2);System.out.println(user);}
}

如果不在同一个包下,则对于default必须setAccessible()
对于public字段自然都不需要setAccessible,对于private字段都需要setAccessible.

那么对于protected呢?在同一个包下自然不需要setAccessible,而对于其子类是什么情况?

package reflect.test;import reflect.bean.User;import java.lang.reflect.Field;/*** @author* @version 1.0* @description: TODO* @date 2025/8/4 20:35*/
public class SubTest extends User {public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {Class<User> userClass = User.class;Field salary1 = User.class.getDeclaredField("salary");salary1.set(userClass,199.3);System.out.println(userClass);}
}

发现报错:

Exception in thread "main" java.lang.IllegalAccessException: class reflect.test.SubTest cannot access a member of class reflect.bean.User with modifiers "protected"at java.base/jdk.internal.reflect.Reflection.newIllegalAccessException(Reflection.java:392)at java.base/java.lang.reflect.AccessibleObject.checkAccess(AccessibleObject.java:674)at java.base/java.lang.reflect.Field.checkAccess(Field.java:1102)at java.base/java.lang.reflect.Field.set(Field.java:797)at reflect.test.SubTest.main(SubTest.java:17)

子类可以通过 this 或 super 直接访问继承的 protected 字段(即使跨包)。

public class SubTest extends User {public void modifySalary() {this.salary = 1000;    // 允许(通过子类实例访问)super.salary = 1000;   // 允许(通过 super 访问)}
}

禁止访问:子类不能通过父类实例访问 protected 字段(跨包时):

User user = new User();
user.salary = 1000;  // 编译错误!跨包时不允许

(2) 反射访问(Field.set())
默认禁止:反射 API 对访问控制的检查比普通代码更严格,即使子类通过反射访问父类的 protected 字段,也会抛出 IllegalAccessException。

必须要显式调用 setAccessible(true) 绕过检查

访问对象属性和修改对象属性

 @Testpublic void testOperation2() throws NoSuchFieldException, IllegalAccessException {User user = new User("zx", 22, "222");Field age = User.class.getDeclaredField("age");age.setAccessible(true);Object o = age.get(user);System.out.println(o);}
@Testpublic void testOperation() throws NoSuchFieldException, IllegalAccessException {Field location = User.class.getField("location");User user = new User();location.set(user,"beijing");System.out.println(user);Field id = User.class.getDeclaredField("id");id.setAccessible(true);id.set(user,"222");System.out.println(user);Field age = User.class.getDeclaredField("age");age.setAccessible(true);age.set(user,11);System.out.println(user);Field salary = User.class.getDeclaredField("salary");salary.set(user,19992.1);System.out.println(user);}
http://www.dtcms.com/a/314488.html

相关文章:

  • 消息系统技术文档
  • 抽像代数概念理解——陪集(coset)
  • 华为2288H V5服务器闪红灯 无法开机案例
  • SpringBoot整合t-io是websocket实时通信
  • 题单【排序】
  • linux中 多进程 导致cuda错误的问题解决
  • 【测试】⾃动化测试常⽤函数
  • 配置Mybatis环境
  • 向量魔法:Embedding如何赋能大模型理解世界
  • 靶场(二十八)---小白心得靶场体会---Mantis
  • 嵌入式开发学习———Linux环境下IO进程线程学习(三)
  • DolphinScheduler 集成DataX
  • 前端VUE基础环境搭建
  • opencv引入libavif
  • typeof和instanceof区别
  • 静电干扰误报率↓85%!陌讯多模态融合算法在智慧环卫检测优化
  • python基础:数据解析BeatuifulSoup,不需要考虑前端形式的一种获取元素的方法
  • 【前端】JavaScript基础知识及基本应用
  • 【AMD】编译llama.cpp实践版
  • 管家级教程:在 Windows 上配置 WSL2、CUDA 及 VLLM,开源音频克隆项目
  • 解决 Alpine 容器中编译 confluent-kafka-go 报错的问题
  • LLaMA-Factory微调教程4:模型评估
  • Spring Boot + ShardingSphere 分库分表实战
  • 【CVPR2025】计算机视觉|AnomalyNCD:让工业异常分类“脱胎换骨”!
  • 计算机视觉(2)车规摄像头标准
  • YOLO11涨点优化:原创自研DSAM注意力!基于BiLevelRoutingAttention的颠覆性升级
  • nodejs 封装方法将打印日志输出到指定文件
  • javacc实现简单SQL解析器
  • Llama 3词汇表揭秘:128,000个token解析:merges 是子词分词算法
  • 数据结构——单向链表部分操作及valgrind安装