Java反射

反射机制是Java编程中的重要特性,它允许程序在运行时动态获取类的信息并进行操作。通过Class类,可以获取类的属性、方法、构造器,并能创建对象和调用方法。反射的应用广泛,如在框架开发、插件功能实现等方面起到关键作用。然而,反射也存在性能损耗、安全风险等问题,需要谨慎使用。
摘要由CSDN通过智能技术生成

反射

​ 在运行状态中,对于任意一个类都能够知道这个类的所有属性和方法;并且对于任意一个对象,都能调用它的任意一个方法;这种动态获取信息及动态调用对象方法的功能称为Java语言的反射机制。

类的执行过程

​ 类的执行过程可以分为4个部分:编译、加载、连接、初始化。

​ (1)编译。就是将源文件编译成字节码文件的过程,即将.java文件编译成.class文件。

​ (2)加载。就是把.class文件通过虚拟机加载到内存中。

​ (3)连接。这个过程分为三个阶段。

​ 验证阶段:主要检验.class文件的格式是否规范。

​ 准备阶段:正式的给类变量(static变量),分配内存,并给内存中的变量赋原值。

​ 解析阶段:将栈内存中的引用变量指向堆内存中的数据,并分配内存地址。

​ (4)初始化。及new实例化类的对象或反射实例化对象。

​ 而类在加载过程中的步骤为:

​ (1)JVM将A.class文件读入内存方法区(运行时内存)

​ (2)JVM将A.class创建唯一的Class类的对象(在堆内存中创建)
在这里插入图片描述

此处的Class是一个实实在在的类,不是一个类关键词class。

	public final class Class<T> implements java.io.Serializable,GenericDeclaration,Type,AnnotatedElement{}

反射的定义

​ 通过Class类的对象可以反向做很多事,如:

(1)获取类的属性、方法

(2)生成类的实例

(3)调用实例的方法、属性

反射通过操作Class类的对象,实现对类的操作以及对对象的操作
在这里插入图片描述

反射使我们在运行时看清一个类的运行情况并使用。

反射是Java被视为动态或准动态语言的关键特性。

反射允许程序在运行时加载、探查、使用一个在编译期可能未知的类。

编译时无法预知对象或类属于什么类型,需要依靠运行时信息来发现真实信息(完整结构、创建实例、操作属性和方法等),此时需要使用反射。

基于反射获取类信息

需要用到一些Reflection API:

java.lang包中的Class类

​ 是反射的核心类,可获取类的属性、方法等信息,生成类的实例。

java.lang.reflect包中的Field类

​ 表示类的成员变量,可以用来获取和设置类的属性值。

java.lang.reflect包中的Method类

​ 表示类的方法,可用来获取类中的方法信息或者执行方法。

java.lang.reflect包中的Constructor类

​ 表示类的构造方法

使用反射的步骤:

(1)获取想要操作的类的Class对象

(2)调用Class类中的方法

(3)使用反射API来操作这些信息

(1)获取Class对象

1.通过Class类的静态方法Class.forName(className) (比较常用的方式)

2.调用对象实例的getClass()方法

3.调用某个类的class属性

(2)Class类中常用的方法

1.获取属性的方法(返回Field类)

getFields() 所有可访问的公共字段(public修饰的字段)

getDeclaredFields() 所有字段

getField(String name) 返回一个特定的公共字段对象

2.获取方法(返回Method类)

getMethods() 所有公共方法,包括从超类(父类)和超接口继承的声明

getDeclaredMethods() 所有方法,但不包括继承的方法

getMethod(String name,Class[]parameterTypes) 返回一个方法对象

(String name 代表方法名,Class[]parameterTypes代表参数类型,无参写null)

getDeclaredMethod(String name,Class[]parameterTypes) 从所有方法中选择特定方法,如果要选用私有方法,需要结合setAccessible(true)(允许私有方法调用)使用。

(3)获取构造方法

getConstructor(Class[]parameterTypes) 返回一个构造方法对象

通过Constructor的newInstance(Object[]initargs)可生成类的实例

通过Method的invoke(Object obj,Object[]args),可在具有指定参数的方法对象上调用此方法对象表示的基础方法。

示例:

	//1.将类的信息装载到jvm中
	Class cla = Class.forName("cn.ref.ChildrenDayPS");
	//2.获取无参构造方法
	Constructor constructor =cla.getConstructor();
	//3.使用反射实例化对象
	Object ps =constructor.newInstance();
	//4.获取打折的方法
	Method method =cla.getMethod("promoteSales",String.class);
	//5.调用实例对象的打折方法
	Double discount = (Double)method.invoke(ps,"1");

使用反射的优缺点

​ 优点:

​ (1)运行期类型的判断,动态类加载

​ (2)提高了程序的灵活性、扩展性,降低耦合性

​ (3)提高自适应能力,无需提前硬编码目标类

​ 缺点:

​ (1)性能问题

​ (2)安全限制

​ (3)内部暴露

​ 反射应用场景:

​ (1)反射机制是目前众多Java框架实现的基础,如:

​ JDBC

​ Hibernate

​ Spring AOP.IoC

​ 分布式微服务

​ (2)实现项目安装插件功能

​ 基于反射,架构师搭建项目框架,自行封装框架,使得项目更加组件化和通用化。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值