Java反射

白日梦组长视频:https://www.bilibili.com/video/BV16h411z7o9?spm_id_from=333.788.videopod.episodes&vd_source=525a280615063349bad5e187f6bfeec3&p=2

博客文章:https://juejin.cn/post/6844904025607897096

什么是反射

Java的反射机制是指在运行状态中,对于任意一个类都能知道这个类所有的属性和方法,并且对于任意一个对象,都能调用它的任意一个方法,无需在编译期确定具体的类和方法

这种动态获取信息以及动态调用对象方法的功能成为Java语言的反射机制

正射

与反射对应的就是正射

在写代码的时候,当需要使用到某一个类的时候,都会先了解这个类是做什么的,然后实例化这个类,接着用实例化好的对象进行操作,这就是正射,如:

1
2
Student student = new Student();
stduent.doHomework("数学")

先实例化一个student对象,然后调用doHomework方法

这段代码在未运行前就已经知道了要运行的类时Student

反射

反射就是一开始不知道要初始化的类对象是什么,就不能使用new关键字来创建对象,如:

1
2
3
4
5
Class clazz = Class.forName("reflection.Student");
Method method = clazz.getMethod("doHomework", String.class);
Constructor constructor = clazz.getConstructor();
Object object = constructor.newInstance();
method.invoke(object, "语文");

这就是获取到一个Student类的原型,然后通过这个原型得到这个类的所有的元信息

这段代码是到整个程序运行的时候,从字符串reflection.Student,才知道要操作的类是Student

反射的作用

  • 让Java具有动态性,因为Java是一个强类型语言,在代码中写好后编译时确定好就不能变了,但通过反射可以让实现类似于PHP中eval("任意代码");的动态执行,传入什么就会执行什么
  • 可以修改已有的属性
  • 动态生成对象
  • 动态调用方法
  • 操作内部类和私有方法

Class对象

RTTI(Run-Time Type Identification)运行时类型识别,作用是在运行时识别一个对象的类型和类的信息

Java在运行时识别对象和类的信息的两种方式:

  • 第一种是传统的RTTI,假定我们在编译期已经知道了所有类型
  • 第二种是反射机制,允许我们在运行时发现和使用类的信息

每个类都有一个Class对象,每当编译一个新类就会产生一个Class对象(保存在一个同名的.class文件中)

Class类的对象作用是运行时提供或获得某个对象的类型信息

image-20251020162341678

image-20251020162419563

如上,创建一个Person类,JVM会创建一个Person对应Class类的Class对象,其中保存了Person类相关的类型信息

image-20251020162614701

反射的使用

获取Class类对象

方法一:使用Class.forName静态方法

1
Class person1 = Class.forName("Person");

方法二:使用.class方法

1
Class person2 = Person.class;

方法三:使用对象.getClass方法

1
2
Person person = new Person();
Class person3 = person.getClass();

image-20251020163826915

反射就是操作获得的Class对象

实例化对象

方法一:使用newInstance方法,无参的

1
Person p = (Person) person1.newInstance();

方法二:使用getConstructor方法,有参的

1
2
Constructor p1 = person1.getConstructor(String.class, int.class);
Person pp = (Person) p1.newInstance("张三", 18);

image-20251020170700649

获取类的属性

方法一:使用getFields方法

这个方法只能获取到public属性

1
Field[] personfields = person1.getFields();

image-20251020172349656

image-20251020172411577

方法二:使用getDeclaredFields方法

1
Field[] personfields2 = person1.getDeclaredFields();

image-20251020172808791

修改对象属性值

修改公有属性值

1
2
Field namefield = person1.getField("name");
namefield.set(pp,"李四");

image-20251020173252019

修改私有属性值

同样的使用getDeclaredFields方法才能修改私有属性的值

还需要加入setAccessible(true)方法才能有权限修改私有属性

1
2
3
Field namefield1 = person1.getField("age");
namefield1.setAccessible(true);
namefield1.set(pp,20);

image-20251020173917293

获取调用类中的方法

获取类中的所有方法

1
Method[] personmethods = person1.getMethods();

image-20251020181229548

调用公有方法

1
2
Method actionmethod = person1.getMethod("action",String.class);
actionmethod.invoke(pp,"123456");

有个action()方法,会打印出传入的参数

image-20251020181333640

image-20251020181416063

调用私有方法

使用getDeclareMethod方法

1
2
Method actionmethod = person1.getDeclareMethod("action",String.class);
actionmethod.invoke(pp,"123456");

Java反射
https://yschen20.github.io/2025/10/20/Java反射/
作者
Suzen
发布于
2025年10月20日
更新于
2025年10月21日
许可协议