反射使用的前提条件:必须先得到代表的字节码的Class,Class类表示.class字节码文件
常见形式为对象.getClass(),即利用反射拿到某个对象的字节码文件,然后利用字节码文件进行相关获取操作
反射机制
Java反射是Java被视为动态(准动态)语言的一个关键性质,这个机制允许程序在运行时通过Reflection APIs(getClass)取得任何一个已知名称的class的内部信息,如其构造方法(Constructors)/方法(Method)/成员变量(Field) 等、并可以在运行时改变fields内容或调用某个方法(所以我们可以利用此特点去越过泛型检查,因为泛型用在编译器期,编译过后会有泛型擦除,所以是可以通过反射去获取相关方法(变量)然后越过泛型检查的)
总结一下:反射就是把Java类中的各种成分映射成为一个个的Java对象
当我们new一个对象的时候,JVM会调用本地class文件,读入到内存中,同时会在内存中产生一个class对象,这个class对象很特殊,这个是必须要且会自动创建的,而且一个类只产生一个class对象(注意区分class对象与class类的实例)
常见反射使用步骤:
先写一个实体类
package Iodemo;
public class TestClass {
int id;
String name;
int age;
public void say(){
System.out.println("i can say");
}
public void eat(){
System.out.println("i can eat");
}
}
然后开始书写我们的测试方法
package Iodemo;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class GetClass {
public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
// 我们还可以使用 Class clazz = Class.forName("Iodemo.TestClass");
// 的方式去获取Class对象
Class clazz = TestClass.class;
TestClass testClass = new TestClass();
// 获取包名+类名
System.out.println(clazz.getName());
// 获取成员方法
Method[] methods = clazz.getMethods();
for (Method method : methods) {
System.out.println(method);
}
// 获取say方法
Method say = clazz.getMethod("say");
System.out.println(say);
// 执行say方法,invoke(该类的实例对象,该方法的参数)
Object result = say.invoke(testClass);
}
}
我们从控制台的返回值可以分析得到: