【JAVA基础】反射

编译期和运行期

首先大家应该先了解两个概念,编译期和运行期,编译期就是编译器帮你把源代码翻译成机器能识别的代码,比如编译器把java代码编译成jvm识别的字节码文件,而运行期指的是将可执行文件交给操作系统去执行,

什么是反射

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

反射就是在运行时才知道要操作的类是什么,并且可以在运行时获取类的完整构造,并调用对应的方法。

使用反射

正常调用:

java 复制代码
Apple apple = new Apple();
apple.setPrice(5);

反射调用

从这个简单的例子可以看出,一般情况下我们使用反射获取一个对象的步骤:

1、获取类的 Class 对象实例

java 复制代码
Class clz = Class.forName("com.zhenai.api.Apple");

2、根据 Class 对象实例获取 Constructor 对象

java 复制代码
Constructor appleConstructor = clz.getConstructor();

3、使用 Constructor 对象的 newInstance 方法获取反射类对象

java 复制代码
Object appleObj = appleConstructor.newInstance();

而如果要调用某一个方法,则需要经过下面的步骤:

1、获取方法的 Method 对象

java 复制代码
Method setPriceMethod = clz.getMethod("setPrice", int.class);

2、利用 invoke 方法调用方法

java 复制代码
setPriceMethod.invoke(appleObj, 14);

class 类对象的三种实例化模式

Class类对象的三种实例化模式

要想解剖一个类,必须先要获取到该类的字节码文件对象。而解剖使用的就是Class类中的方法.所以先要获取到每一个字节码文件对应的Class类型的对象.

Class类对象的三种实例化模式:

反射原理

1.java文件被编译成class文件

当我们编写完一个Java项目之后,每个java文件都会被编译成一个.class文件。

2.class文件加载到JVM

Java程序在运行时,首先需要将需要的类加载到内存中。

这些class文件在程序运行时,会被ClassLoader加载到JVM中,当一个类被加载以后,JVM就会在内存中自动产生一个Class对象,用于描述该类的信息。

3.获取类的Class对象

Java反射的第一步是获取需要操作的类的Class对象,如下所示:

java 复制代码
// 获取Class对象
Class<?> clazz = Class.forName("com.mikechen.MyClass");

Class对象是Java反射的核心,它包含了该类的所有信息,包括构造函数、方法、属性等。

4.获取类的构造函数、方法和属性

在获取到Class对象之后,可以通过反射获取类的构造函数、方法和属性等信息。

java 复制代码
// 获取Person类的Class对象
Class<?> personClass = Class.forName("Person");

// 创建一个Person对象
Constructor<?> constructor = personClass.getConstructor(String.class, int.class);
Object person = constructor.newInstance("Alice", 25);

// 获取name属性并且输出它的值
Field nameField = personClass.getDeclaredField("name");
nameField.setAccessible(true);
String name = (String) nameField.get(person);
System.out.println(name);

// 设置name属性的值
nameField.set(person, "Bob");
System.out.println(((Person) person).getName());

// 获取sayHello方法并且调用它
Method sayHelloMethod = personClass.getDeclaredMethod("sayHello");
sayHelloMethod.invoke(person);

这样我们就可以通过Java反射获取到类的所有信息了。

5.Java反射方法

Java反射方法常见的有:

getConstructors():获取类的所有public构造函数;

getDeclaredConstructors():获取类的所有构造函数,包括public和非public;

getMethods():获取类的所有public方法,包括从父类继承而来的方法;

getDeclaredMethods():获取类的所有方法,包括public和非public;

getFields():获取类的所有public属性,包括从父类继承而来的属性;

getDeclaredFields():获取类的所有属性,包括public和非public;

反射的优缺点

1、优点:

在运行时获得类的各种内容,进行反编译,对于Java这种先编译再运行的语言,能够让我们很方便的创建灵活的代码,这些代码可以在运行时装配,无需在组件之间进行源代码的链接,更加容易实现面向对象。

2、缺点:

(1)反射会消耗一定的系统资源,因此,如果不需要动态地创建一个对象,那么就不需要用反射;

(2)反射调用方法时可以忽略权限检查,因此可能会破坏封装性而导致安全问题。

反射的用途

1、反编译:.class-->.java

2、通过反射机制访问java对象的属性,方法,构造方法等

3、当我们在使用IDE,比如Ecplise时,当我们输入一个对象或者类,并想调用他的属性和方法是,一按点号,编译器就会自动列出他的属性或者方法,这里就是用到反射。

4、反射最重要的用途就是开发各种通用框架。比如很多框架(Spring)都是配置化的(比如通过XML文件配置Bean),为了保证框架的通用性,他们可能需要根据配置文件加载不同的类或者对象,调用不同的方法,这个时候就必须使用到反射了,运行时动态加载需要的加载的对象。

5、例如,在使用Strut2框架的开发过程中,我们一般会在struts.xml里去配置Action,比如

java 复制代码
<action name = "login" class="com.xiazi.test.LoginAction">
<result>login.jsp</result>
</action>

比如我们请求login.action时,那么StrutsPrepareAndExecuteFilter就会去解析struts.xml文件,从action中查找出name为login的Action,并根据class属性创建SimpleLoginAction实例,并用Invoke方法来调用execute方法,这个过程离不开反射。配置文件与Action建立了一种映射关系,当View层发出请求时,请求会被StrutsPrepareAndExecuteFilter拦截,然后StrutsPrepareAndExecuteFilter会去动态地创建Action实例。

比如,加载数据库驱动的,用到的也是反射。

java 复制代码
Class.forName("com.mysql.jdbc.Driver");

类的加载时机

1、静态加载

当新创建一个对象时(new),该类会被加载;

当调用类中的静态成员时,该类会被加载;

当子类被加载时,其超类也会被加载;

2、动态加载

通过反射的方式,在程序运行时使用到哪个类,该类才会被加载;

反射应用场景

1.动态代理

使用反射可以在运行时动态地创建代理类,这在实现AOP(面向切面编程)时非常有用。

2.注解处理器

使用反射可以在运行时动态地解析注解,并执行注解所定义的操作,例如生成代码或加载配置文件。

3.依赖注入

使用反射可以在运行时动态地实例化对象,并将其注入到其他对象中,从而实现依赖注入的功能。

4.反射工厂

使用反射可以在运行时动态地创建对象,并执行对象的方法,这对于编写通用代码非常有用。

相关推荐
唔好理总之好犀利6 分钟前
华为OD 小明找位置 C语言实现
java·数据结构·算法
焚琴煮鹤的熊熊野火6 分钟前
Lodash——JavaScript中的工具库
开发语言·前端·javascript
上官花雨43 分钟前
第一章 Spring Boot入门
java·spring boot·后端
tingmailang1 小时前
idea插件开发(一)合并检查
java·ide·架构·intellij-idea·开源软件
心死翼未伤1 小时前
python从入门到精通:文件操作
开发语言·前端·javascript·数据结构·python·json
FantanLee1 小时前
idea debug 各个步骤含义
java·intellij-idea
Seven 7 Chihiro1 小时前
学生管理系统升级(登录注册 + 关联学生管理系统)
java·开发语言
techpupil1 小时前
idea便捷操作
java·ide·intellij-idea
9毫米的幻想1 小时前
【C++】—— 模版初阶
java·c语言·开发语言·c++·学习
小笨猪-1 小时前
Spring事务和事务传播机制
java·数据库·spring