一:什么是反射机制?
- 反射就是通过获取到该类的字节码文件对象—->Class类对象,通过Class类对象获取该类里面的一些属性(成员变量),构造方法
二:三种获取字节码文件对象的方法
1)Object类中的getClass()方法,表示正在运行的那个类:Class类
2)数据类型的class属性 举例:String.class,Student.class
3)Class类中的特有方法:forName(String className):
public static Class<?> forName(String className) //该类的全路径名称
// 返回与带有给定字符串名的类或接口相关联的 Class 对象。
public Constructor<T> getConstructor(Class<?>... parameterTypes)
//返回一个Constructor 对象,它反映此 Class 对象所表示的类的指定公共构造方法
public T newInstance(Object... initargs):传递的是实际参数
//表示的构造方法来创建该构造方法的声明类的新实例,并用指定的初始化参数初始化该实例
public Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes)
//表示获取类或者接口中的指定的构造方法
public void setAccessible(boolean flag):
// 在访问的时候取消java语言访问检查(强制性)
public Field[] getFields():
//所有的公共的可访问的字段,返回的是Field对象数组
public Field[] getDeclaredFields():
//获取当前字节码文件对象中所有的公共的或者私有的字段
public void set(Object obj, Object value)
//给obj实例对象里面的成员变量设置一个实际参数---->value
public Method[] getMethods():
//获取当前该字节码文件对象(Person.class)中自己本身以及它父类中所有的公共成员方法
public Method[] getDeclaredMethods():
//获取当前字节码文件对象本身所有的成员方法
public Object invoke(Object obj, Object... args)
* 参数1:表示当前针对哪个以实例对象进行方法的调用
* 参数2:当前调用该方法的时候里面传递的实际参数
invoke代码示例
public class ArrayListTest {
public static void main(String[] args) throws
NoSuchMethodException,
SecurityException, IllegalAccessException,
IllegalArgumentException,
InvocationTargetException {
//创建ArrayList对象
ArrayList<Integer> array = new ArrayList<Integer>() ;
//给集合中添加元素
// array.add(100) ;
// array.add("hello") ;
//利用反射类来给集合中添加字符串数据
//获取该ArrayList类的字节码文件对象
Class c = array.getClass() ;
//有了ArrayList.class字节码文件对象了
//已经有了构造器对象:array
//可以通过反射在获取公共的访问:add(E e)
Method m = c.getMethod("add",Object.class) ;
//调用用底层invoke(当前字节码文件对象的实例,实际参数)
m.invoke(array, "hello") ;
m.invoke(array, "world") ;
m.invoke(array, "java") ;
System.out.println(array);
}
}
二:动态代理
1.接口 InvocationHandler
Object invoke(Object proxy, Method method, Object[] args)
在代理实例上处理方法调用并返回结果。
代码示例:
package org.westos.reflect_handler2;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class MyInvocationHandler implements InvocationHandler {
//目标对象(需要给哪一个对象设置这个代理呢?)
private Object target ;
//无参构造
public MyInvocationHandler(Object target){
this.target = target ;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
//权限校验
System.out.println("权限校验");
Object result = method.invoke(target, args) ;
//日志记录
System.out.println("日志记录");
return result; //返回值就是代理对象
}
}