基本概念#
- 通常情况下编写代码都是固定的,无论运行多少次执行的结果也是固定的,在某些特殊场合中编写代码时不确定要创建什么类型的对象,也不确定要调用什么样的方法,这些都希望通过运行时传递的参数来决定,该机制叫做动态编程技术,也就是反射机制。
- 通俗来说,反射机制就是用于动态创建对象并且动态调用方法的机制。
- 目前主流的框架底层都是采用反射机制实现的。
- 如:
Person p= new Person(); //表示声明 Person类型的引用指向 Person类型的对象
p.show(); // 表示调用 Person类中的成员方法show
Class类#
甚本概念#
java.lang.Class
类的实例可以用于描述java应用程序中的类和接口,也就是一种数据类型。
- 该类没有公共构造方法,该类的实例由java虚拟机和类加载器自动构造完成,本质上就是加载到内存中的运行时类。
获取 Class对象的方式#
- 使用数据类型
.class
的方式可以获取对应类型的 Class对象
- 使用引用/对象
.getClass()
的方式可以获取对应类型的Class对象。
- 使用包装类
.TYPE
的方式可以获取对应基本数据类型的Class对象
- 使用
Class.forName
的方式来获取参数指定类型的Class象
- 使用类加载器
ClassLoader
的方式获取指定类型的Class对象
常用方法#
方法声明 |
功能介绍 |
static Class< ? > forName(String className) |
用于获取参数指定类型对应的class对象并返回 |
T newInstance() |
(已过时 请使用Constructor类)用于创建该Cass对象所表示类的新实例 |
Constructor类#
基本概念#
java.lang.reflect.Constructor
类主要用于描述获取到的构造方法信息。
Class类的常用方法#
方法声明 |
功能介绍 |
Constructor< T > getConstructor( Class< ? >...parrmeterTypes) |
用于获取此Class对象所表示类型中参数指定的公共构造方法 |
Constructor< ? > [] getConstructors() |
用于获取此Class对象所表示类型中所有的公共构造 |
Constructor类的常用方法#
方法声明 |
功能介绍 |
T newInstance(object...initargs) |
使用此 Constructor对象描述的构造方法来构造Cass对象代表类型的新实例 |
int getModifiers() |
获取方法的访问修饰符 |
String getName() |
获取方法的名称 |
Class< ? >[] getParameterType() |
获取方法所有参数的类型 |
使用反射机制创建实例#
import java.io.*;
import java.lang.reflect.Constructor;
public class PersonTest {
public static void main(String[] args) {
FileInputStream fis = null;
InputStreamReader isr = null;
BufferedReader br = null;
try {
fis = new FileInputStream("./config.txt");
isr = new InputStreamReader(fis);
br = new BufferedReader(isr);
String line = br.readLine();
Class forName = Class.forName(line);
System.out.println("动态加载的类为:" + forName);
Constructor constructor = forName.getConstructor();
System.out.println("使用无参构造的对象是:" + constructor.newInstance());
Constructor constructor1 = forName.getConstructor(int.class, String.class);
System.out.println("使用有参构造获取到的对象是:" + constructor1.newInstance(10,"feng"));
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (null != fis) {
fis.close();
}
if (null != isr) {
isr.close();
}
if (null != br) {
br.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
Field 类#
基本概念#
java.lang.reflect.Field
类主要用于描述获取到的单个成员变量信息。
Class类的常用方法#
方法声明 |
功能介绍 |
Field getDeclaredField(String name) |
用于获取此Cas对所表示类中参数指定的单个成员变量信息 |
Field getDeclaredFields() |
用于获取此Class对象所表示类中所有成员变量信息 |
Field类的常用方法#
方法声明 |
功能介绍 |
Object get(Object obj) |
取参数对象Object中此Field对象所表示成员变量的数值 |
void set(Object obj, Object value) |
将参数对象Object中此Field对象表示成员变量的数值修改为参数vlaue的数值 |
void setAccessible(boolean flag) |
当实参传通true时,则反射对象在使用时应该取消Java语言访问检查 |
int getModifiers() |
获取成员变量的访问修饰符 |
Class< ? > getType() |
获取成员变量的数据类型 |
String getName() |
取成员变量的名称 |
获取和修改成员变量#
import java.io.*;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
public class PersonTest {
public static void main(String[] args) {
FileInputStream fis = null;
InputStreamReader isr = null;
BufferedReader br = null;
try {
fis = new FileInputStream("./config.txt");
isr = new InputStreamReader(fis);
br = new BufferedReader(isr);
String line = br.readLine();
Class forName = Class.forName(line);
Constructor constructor1 = forName.getConstructor(int.class, String.class);
System.out.println("使用有参构造获取到的对象是:" + constructor1.newInstance(10, "feng"));
Object object = constructor1.newInstance(10, "feng");
Field field = forName.getDeclaredField("name");
field.setAccessible(true);
Object v = field.get(object);
System.out.println("获取到成员变量的值为:" + v);
field.set(object, "li");
v = field.get(object);
System.out.println("修改后的成员变量值为:" + v);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (null != fis) {
fis.close();
}
if (null != isr) {
isr.close();
}
if (null != br) {
br.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
Method类#
基本概念#
java.lang.reflect.Method
类主要用于描述获取到的个成员方法信息。
Class类的常用方法#
方法声明 |
功能介绍 |
Method getMethod(String name, Class< ? >...parameterTypes) |
用于获取该Class对象表示类中名字为name参数为parameterTypes的指定公共成员方法 |
Method getMethods() |
用于获取该Cass对象表示类中所有公共成员方法 |
Method类的常用方法#
方法声明 |
功能介绍 |
Object invoke(Object obj, Object...args) |
使用对象obj来调用此 Method对象所表示的成员方法,实参传递args |
int getModifiers() |
获取方法的访问修饰符 |
Class< ? > getReturnType() |
获取方法的返回值类型 |
String getName() |
获取方法的名称 |
Class< ? > getParameterTypes() |
获取方法所有参数的类型 |
Class< ? > getExceptionTypes() |
获取方法的异常信息 |
获取方法及调用方法#
import java.io.*;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class PersonTest {
public static void main(String[] args) {
FileInputStream fis = null;
InputStreamReader isr = null;
BufferedReader br = null;
try {
fis = new FileInputStream("./config.txt");
isr = new InputStreamReader(fis);
br = new BufferedReader(isr);
String line = br.readLine();
Class forName = Class.forName(line);
Constructor constructor1 = forName.getConstructor(int.class, String.class);
System.out.println("使用有参构造获取到的对象是:" + constructor1.newInstance(10, "feng"));
Object object = constructor1.newInstance(10, "feng");
Method setName = forName.getMethod("setName", String.class);
Method getName = forName.getMethod("getName");
setName.invoke(object, "Hello");
Object invoke = getName.invoke(object);
System.out.println("获取到的值为:" + invoke);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (null != fis) {
fis.close();
}
if (null != isr) {
isr.close();
}
if (null != br) {
br.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
获取其它结构信息#
方法声明 |
功能介绍 |
Package getPackage() |
获取所在的包信息 |
Class< ? super T > getSuperClass() |
获取继承的父类信息 |
Class< ? >[] getInterfaces() |
获取实现的所有接口 |
Annotation[] getAnnotations() |
获取注解信息 |
Type[] getGenericInterfaces() |
获取泛型信息 |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)