反射-01 问题提出

问题:

在BlindBox类中有1024个open开头方法,方法会已返回从1~1024之间的整数且不会重复,问哪个方法会返回666(不能查看源码),别人可能对源码进行加密了,能不能用以前的方法解决呢? 一个个试一下,但这需要足够耐心

1
2
3
4
5
public class Test1 {
public static void main(String[] args) throws Exception {

}
}

思考: 如何在一个类的众多方法中找出一个特殊的?

如果有那么一种方法,能知道这个类中有所有方法并且遍历调用它们,这个问题就迎刃而解

反射-02 什么是反射

反射? ==> 光反射 我们通过镜子可以看清自己,反射即认清自己

让对象认清自己

  • 类名
  • 父类
  • 接口
  • 成员变量
  • 方法

并非所有语言具备认清对象自己的能力,比如C++,别忘了,我们的代码需要通过编译变成机器码然后再加载到内存中去运行,C++在编译运行以后有些信息就丢失了

image-20250322091211702.png

反射-03 java反射原理

image-20250322091345078.png

java会把这些信息记录下来,在类加载的时候放在一个特殊的一个对象中

image-20250322091436229.png

这个InstanceKlass 本质上是一个c++对象,虽然记录了这些信息,但是无法直接使用,jvm作者为我们留好了一个后门叫_java_mirror 直接翻译过来叫java镜像,我们直接叫他student.class,以后称之为类对象,通过一些列类方法就能够间接访问到类信息了

image-20250322091700824.png

反射-04 问题解决

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class Test1 {
public static void main(String[] args) throws Exception {
Method[] methods = BlindBox.class.getMethods(); //获取所有的方法和响应的参数
//修饰符 返回值 static/final
for(Method method : methods){

if(method.getName().startsWith("open")){
//System.out.println(method.getName());
System.out.println(methods.invoke(null));
if(methods.invoke(null).equals(666)){
System.out.println(method.getName());
}
}
}
}
}