Java 反射(reflective)
什么是反射?能够分析类能力的程序称为反射 ( reflective )
反射机制的功能有什么?
·在运行时分析类的能力
·在域运行时查看对象,例如,编写一个 toString 方法供所有类使用
·利用Method对象,这个对象很像C++中的函数指针
一. Class类
·最常用的Class方法是 getName,这个方法将返回类的名字
·还可以调用静态方法 forName 获得类名对应的 Class 对象(上两点的前提是类名保存在字符串中,并可在运行时改变)
1.1 获得一个Class类型的对象
①Object类中的 getClass() 方法将会返回一个class类型的实例
②可以调用静态方法 forName 获得类名对应的 Class 对象
String className = "java.util.Random"
Class cl = Class.forName(className)
③这种方法非常简单,如果T是表示任意的Java类型(或void关键字),T.class 将代表匹配的类的对象
Class cl = Random.class; //当你import了 java.util.*包;
二.利用反射分析类的能力
反射机制最重要的内容——检查类的结构,在java.lang.reflect包中,不同类中的各个方法,能分别返回类提供的 public域、方法和构造器数组,成员等。
查看任意对象的数据域名称和类型的方法①获得对应的Class对象 ②通过Class对象调用getDeclaredFields
打印一个类的全部信息方法,直接输入java.包.类,例如:
java.lang.Double
三.运行时使用反射分析对象
利用反射机制可以查看在编译时还不清楚的对象域,查看对象域的关键方法事Field类中的get方法。如果f是一个Field类型的对象,obj是某个包含f域的类的对象,f.get(obj)将返回一个对象,其值为obj域的当前值。
Employee harry = new Employee("Harry Hacker",35000,10,1,1989);
Class cl = harry.getClass();
//类对象表示Employee
Field f = cl.getDeclaredField("name");
//获取 Employee 类中的 name 域
Object v = f.get(harry);
//获取 harry 对象中 name 域的值,抛出IllegalAccessException
因为name是私有域,所以get方法会抛出一个IllegalAccessException,因此为了得到访问权限,需要调用setAccessible方法
f.setAccessible(true); //现在可以使用f.get(harry);
四.使用反射编写泛型数组列表
一开始就是Object[] 的数组永远不能转换成Employee[]数组,为了能创建与原数组类型相同的新数组,需要java.lang.reflect包中Array类的一些方法。
其中最关键的时Array类中的静态方法newInstance,它能够构造新数组。调用它时必须提供两个参数,一个是数组的元素类型,一个是数组的长度。
Object.newArray = Array.newInstance(componentType,newLength);
动态创建数组的方法
public static Object goodCopyof(Object a,int newLength) { Class cl = a.getClass(); if(!cl.isArray()) return null; //判断是否是数组 Class componentType = cl.getComponentType(); //返回 a 数组的类的对象 int length = Array.getLength(a); //以整数形式返回数组a的长度 Object newArray = Array.newInstance(componentType,newLength); //构造新数组 System.arraycopy(a,0,newArray,0,Math.min(length,newLength)); //数组间复制 return newArray; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现