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;
}
复制代码
posted @   Pray386  阅读(236)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示