框架基础技术反射

Java反向概述

反射(Reflection)机制是 Java 语言特性之一,是 Java被视为动态(或准动态)语言的一个关键特性。

Java反射有以下3个动态特性

  • 运行时创建实例
  • 运行期间调用方法
  • 运行时更改属性
Java程序的执行过程
Person.java——》编译器——》Person.class——》Java虚拟机——》运行程序

Java反射可以实现的功能

  • 在运行时探知任意一个实例所属的类
  • 在运行时构造任意一个类的实例
  • 在运行时探知任意一个类所真有的方法和属性
  • 在运行时调用任意一个实例的方法

Java反射常用的API

使用Java反射技术常用的类
  • java.lang.Class<T>类:反射的核心类,反射所有的操作都围绕该类来生成的。
  • java.lang.reflect.Constructor<T>类:表示类的构造方法。
  • java.lang.reflect.Field 类:表示类的属性,可以获取和设置类中属性的值。
  • java.lang.reflect.Method 类:表示类的方法,可以用来获取类中方法的信息或执行方法。

反射的应用

在 Java 程序中使用反射的基本步骤如下

  1. 导入java.lang.reflect 包中的相关类。
  2. 获得需要操作的类的 Class 实例。
  3. 调用Class 实例的方法获取 Field、Method等实例。
  4. 使用反射 API操作实例成员。

获取对应类型基本信息的方法

方法说明
String getName()以字符串形式返回该类型的名称
String getSimpleName()以字符串形式返回该类型的简称(类名)
Package getPackage()获取该类型所在的包
Class getSuperclass()获取该类型的超类的 Class 实例
Class[] getinterfaces()返回该类型所实例的全部接口的 Class 实例
int getModifiers()返回该类型的所有修饰符,由public、protected、private、final、static、abstract等对应的int常量组成,返回的整数应使用Modifier 工具类来解码,才可以判断修饰符的构成。
Class[]getDeclaredClasses()返回该类型中包含的全部内部类的 Class 实例
Class getDeclaringClass()返回该类型所在的外部类的 Class 实例

获取对应类型所含构造方法的方法

方法说明
Constructor getConstructor(Class... params)返回该类型指定参数列表的public 构造方法,构造方法的参数列表与params所指定的类型列表所匹配
Constructorl]getConstructors()返回该类型的所有public 构造方法
Constructor getDeclaredConstructor(
Class... params)
返回该类型的指定参数列表的构造方法,访问级别不限
Constructor[]getDeclaredConstructors()返回该类型的所有构造方法,访问级别不限
ConstructorgetDeclaredConstructor()获取该类型的无参构造函数

获取对应类型所含属性的方法

方法说明
Field getField(String name)返回该类型中指定名称的public属性,name参数用于指定属性名称。例如:clz.getField("age");//clz为某 Class对象,age 为属性名
Field[] getFields()返回该类型中所有public属性
Field getDeclaredField(String name)返回该类型中指定名称的属性,与属性的访问级别无关
Field[] getDeclaredFields()返回该类型中的全部属性,与属性的访问级别无关

访问类包含方法的方法

方法说明
Method getMethod(
String name, Class... params)
返回该实例中指定的public方法,name参数用于定方法名称,params参数指定参数列表
Method[] getMethods()返回该实例中所有public方法
Method getDeclaredMethod(
String name, Class... params)
返回该实例中指定的方法,与方法的访问级别无关
Method[lgetDeclaredMethods()返回该实例中的全部方法,与方法的访问级别无关

通过反射来创建 Java 类型的实例有如下两种方式

通过反射来创建 Java 类型的实例有如下两种方式

  • 使用 Class 实例的 newinstance()方法创建相关类型的实例。
  • 使用 Constructor 实例创建相关类型的实例。

构造方法来创建Java对象的步骤

  1. 获取与该类型相关的 Class 实例。
  2. 调用 Class 实例的方法获取表示指定构造方法的 Construetor 实例。
  3. 调用Constructor 实例的 newinstance()方法来创建相关类型的实例。
注意:

受访问修饰符的限制,使用反射方式访问超出访问范围的构造方法、属性、方法时,会引发 java.lang.legalAccessException 异常。若要禁止 Java 语言访问检查强行访问,需要设置相关实例为可访问,语法如下。
c3.setAccessible(true);// 通过构造方法/属性/方法实例调用
当然此种做法会破坏封装,需谨慎使用

访问属性的方法

方法说明
xxx getXxx(Object obj)xx表示8种基本数据类型之一,如int getInt(0bjectobj).obj 为该属性所在类的实例。假设instance 表示A类的实例,field 表示A类中的属性 a,则 field.getInt(instance)表示 以int类型返回 instance中属性a的值。若 Field 实例表示的是一个静态属性,则obj可以设置为 null
Object get(object obj)以 object 类型返回 obj 中相关属性的值
void setXxx(Object obj, xxx val)将 obj中相关属性的值设置为val。xxx为8种基本数据类型之一
void set(Object obj, Object val)将 obj中相关属性的值设置为 val
void setAccessible(boolean flag)

对相关属性设置访问权限。设置为true可以禁止Java语言访问检查

知识扩展:

在 java.lang.reflect包下还提供了一个 Array 类,Array 实例可以代表一个数组。程序可以使用 Array 类来动态地创建数组及操作数组元素等。

类的部分常用方法

方法说明
static Object newinstance(ClasscomponentType, int length)创建元素类型为componentType,长度为length的数组
static Obiect newinstance(ClasscomponentType,int...dimensions)创建多维数组,元素类型是 componentType,维数是 dimensions.length,dimensions 中的每一个元素决定每一维的长度
static int getLength(Object arr)返回数组 arr 的长度
static xxx getXxx(Object arr int index)xx表示8种基本数据类型之一,以基本数据返回数组 arr 的长度类型返回数组 arr中索引为index的元素
static Object get(Object arr int index)以object 类型返回数组 arr 中索引为index 的元素
static void setXxx(Object arr, int index, xxx val)将 val 赋值给数组 arr 中索引为 index 的元素,xxx为8种基本数据类型之一
static void set(Object arr, int index, Object val)将 val赋值给数组 arr 中索引为index的元素

如下的代码中,创建了数组 arr,并为元素赋值。
//创建一个元素类型为String,长度为10的数组Object arr = Array.newinstance(String. class, 10);//为数组 arr中index为5的元素赋值
Array.set(arr , 5,"Jack");
//取出数纽arr 中index为5的元素的值Object o= Array .get(arr ,5);
使用 Array 类可以动态灵活地创建和操作数组,Array 类的更多方法可以在使用时査看’Java API。

注意:

使用反射虽然会很大程度上提高代码的灵活性,但是不能滥用反射,因为通过反射创建和访问实例时性能要稍微低一些,且反射可能会破坏封装。实际上,只有当程序需要动态创建类的实例时才会考虑使用反射通常,在通用性较广的框架、基础平台中反射技术会有大量的运用。类似于实战任务4所实现的数据动态处理能力,在很多Java 框架中都有更完善、更强大的实现,如将请求数据自动封装到 JavaBean、对JavaBean 中的属性值进行格式校验、将 SQL 查询结果封装到JavaBean、将 JavaBean 属性值赋值给 SQL查询条件等,都需要程序能够动态创建和操作 Java实例,这就必须使用反射技术。理解Java 反射机制,对以后学习框架技术会有很大的帮助。

  • 6
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值