反射就是从类里拿东西
有的人可能会想为什么不能用io流,从上往下一行一行的读也能获取类中的信息,为什么要用反射呢?
假如我们io流,从左到右一行一行的读取数据,如果碰到局部变量和成员变量同名,怎么区分,还得结合上下文,比较麻烦
但用反射可以一步一步的扒出所有信息
!!!思考:怎样用反射扒出所有信息,它是通过什么手段实现的
回顾: 当我们编写好以.java为扩展名的文件后,如果它能被运行(比如其中包含main函数),那么我们能通过点击IDEA里的运行按钮运行这个.java文件。
但IDEA向我们隐藏了一个关键步骤:它首先是把.java文件编译成扩展名是.class的字节码文件,随后,Java的虚拟机(JVM)在当前的操作系统上(比如window 10)上运行这个.class文件。
想:通过某些工具,我们能打开.class文件,并也能看到其中包含的属性和方法,但我们不能直接针对.class文件编程,我们得使用Class(C是大写)这个类(规则)。当一个类或接口被装入到Java虚拟机
(JVM)时便会产生一个与和它相关联的java.lang.Class对象,我们就可以通过这个产生class对象来访问和使用目标类的属性和方法,而反射的作用就是如此
所以要实现反射
先获去class对象A
通过class对象的方法、获取构造方法的对象、使用构造方法对象的方法得到它的各种信息,此外通过获取的构造方法还可以创建对象
通过class对象的方法、获取成员变量的对象、使用成员变量对象的方法得到它的各种信息
通过class对象的方法、获取成员方法的对象、使用成员方法对象的方法得到它的各种信息,此外还可以运行方法
获取class字节码文件的对象


1对应public
获取成员变量的对象(对象属于Field类)
获取成员方法的对象(对象属于Method类)
//一.获取class字节码文件的对象
Class aClass = Class.forName("java_3gao.com.hz.test.Student");
//二.①获取构造方法的对象(这里举例获取private Student(String name, int age) 构造方法)
//单个构造方法的对象
Constructor constructor = aClass.getDeclaredConstructor(String.class,int.class);
//②使用获取的构造方法得到它的各种信息
System.out.println(constructor.getModifiers());//返回修饰符对应的数字:1对应
public,2对应private
System.out.println(constructor.getParameterCount());//返回方法的参数个数
//③通过获取的构造方法来创建对象
// setAccessible(true)是取消java修饰符检查,即构造方法虽然是private也能在这里创建对象)
constructor.setAccessible(true);
Student s1 = (Student)constructor.newInstance("王五", 16);
System.out.println(s1.toString());
//三.①获取成员变量的对象
//单个成员变量的对象
Field field = aClass.getDeclaredField("name");
//②使用获取的构造方法得到它的各种信息
System.out.println(field.getModifiers());//返回修饰符对应的数字:1对应
public,2对应private
System.out.println(field.getType());//返回变量数据类型
//③获取成员变量的值(注意变量为私有,所以还要用 setAccessible(true)取消检查)
Student s2 = new Student("小王");
field.setAccessible(true);
System.out.println(field.get(s2));
//四.获取成员方法的对象
//①获取单个成员方法的对象
Method method = aClass.getMethod("toString");
//②使用获取的成员变量对象得到它的各种信息
System.out.println(method.getModifiers());//返回修饰符对应的数字:1对应
public,2对应private
System.out.println(method.getParameterCount());//返回参数个数
//③方法运行(方法的调用者,还有传参invoke(Object obj, Object... args)第一个参数的方法的调用者是谁,第二个是传的参数,这个方法无参所以不传)
method.setAccessible(true);
String result= (String) method.invoke(s1);
System.out.println(result);