Java 中反射总的来说就是获得Class实例,通过这个Class实例来获取类的信息从而可以实例化该类或者调用方法
1. 获得Class实例
一共有三种方法获得
Class clazz = Class.forName("cn.sheep3.efjava.reflect.Persen");
Class clazz = Demo.class;
Class clazz = demo.getClass();
2. 通过Class实例获得类信息
//获得构造器
clazz.getConstructors();
//获得接口
clazz.getInterfaces();
//获得注解
clazz.getAnnotations()
//获得父类
clazz.getSuperclass()
//获得修饰符
clazz.getModifiers()
//获得方法
clazz.getMethods()
3. getDeclaredXxx 与 getXxx
getDeclaredXxx 获得自身所有的Xxx
getXxx 获得所有Xxx包括父类
4. 实例化对象
//两种方式
//java.lang.Class.newInstance()
Object obj = Class.forName("java.lang.Object").newInstance();
//java.lang.reflect.Constructor.newInstance()
Constructor<?>[] cons = clazz.getConstructors();
per1 = (Person) cons[0].newInstance();
5. 调用方法
//先获得Method实例
Method declaredMethod = clazz.getDeclaredMethod("getAge");
//调用Method实例的invoke方法,第一个参数是对象实例,后面的可变参数是方法参数
Object m_return = declaredMethod.invoke(person);
6. 绕过访问控制
只需要在获取到Constructor、Field和Method类的对象之后,调用setAccessible方法并设为true即可
7. 动态代理
实现InvocationHandler接口
重写invoke(),在这里hook目标方法
获得proxy实例(List) Proxy.newProxyInstance(类加载器, Class[], InvocationHandler的实现)
通过这个proxy来调用方法