反射的使用
获取class对象的三种方式
//类名全路径Class<?> clazz1 = Class.forName("test.User");Class clazz2 = User.class;Class clazz3 = new User().getClass();
获取构造方法
// 获取"参数是parameterTypes"的public的构造函数public Constructor getConstructor(Class[] parameterTypes)// 获取全部的public的构造函数public Constructor[] getConstructors()// 获取"参数是parameterTypes"的,并且是类自身声明的构造函数,包含public、protected和private方法public Constructor getDeclaredConstructor(Class[] parameterTypes)// 获取类自身声明的全部的构造函数,包含public、protected和private方法public Constructor[] getDeclaredConstructors()// 如果这个类是"其它类的构造函数中的内部类",调用getEnclosingConstructor()就是这个类所在的构造函数;若不存在,返回nullpublic Constructor getEnclosingConstructor()
Class<?> clazz = Class.forName("test.User");//获得默认构造函数Constructor<?> constructor = clazz.getDeclaredConstructor(null);Object object1 = constructor.newInstance();//获得含参构造函数Constructor<?> constructor2 = clazz.getDeclaredConstructor(new Class[]{int.class, String.class});Object object2 = constructor2.newInstance(1, "123456");
获取成员方法
// 获取“名称是name,参数是parameterTypes”的public的函数(包括从基类继承的、从接口实现的所有public函数)public Method getMethod(String name, Class[] parameterTypes)// 获取全部的public的函数(包括从基类继承的、从接口实现的所有public函数)public Method[] getMethods()// 获取“名称是name,参数是parameterTypes”,并且是类自身声明的函数,包含public、protected和private方法。public Method getDeclaredMethod(String name, Class[] parameterTypes)// 获取全部的类自身声明的函数,包含public、protected和private方法。public Method[] getDeclaredMethods()// 如果这个类是“其它类中某个方法的内部类”,调用getEnclosingMethod()就是这个类所在的方法;若不存在,返回null。public Method getEnclosingMethod()
Class<?> clazz = Class.forName("test.User");//获取全部的类自身声明的函数,包含public、protected和private方法。Method[] declaredMethods = clazz.getDeclaredMethods();//获取方法名为printInfo,方法参数类型任意的方法Method printInfo = clazz.getDeclaredMethod("printInfo", new Class[]{});User user = (User) clazz.newInstance();//invoke传入的参数是这个方法所属的对象,以及方法的参数//可以调用类中的任意方法,包括私有方法printInfo.invoke(user, null);
获取成员变量
// 获取“名称是name”的public的成员变量(包括从基类继承的、从接口实现的所有public成员变量)public Field getField(String name)// 获取全部的public成员变量(包括从基类继承的、从接口实现的所有public成员变量)public Field[] getFields()// 获取“名称是name”,并且是类自身声明的成员变量,包含public、protected和private成员变量。public Field getDeclaredField(String name)// 获取全部的类自身声明的成员变量,包含public、protected和private成员变量。public Field[] getDeclaredFields()
Class<?> clazz = Class.forName("test.User");Field[] fields = clazz.getDeclaredFields();// 创建并通过反射,修改一个 private 变量 idUser user = (User) clazz.newInstance();Field field = clazz.getDeclaredField("id");//private属性要设置为truefield.setAccessible(true);field.set(user, 123);
获取注解和父类
// 获取类的"annotationClass"类型的注解public Annotation<A> getAnnotation(Class annotationClass)// 获取类的全部注解,不能获取继承的注解public Annotation[] getAnnotations()// 获取类自身声明的全部注解public Annotation[] getDeclaredAnnotations()// 获取实现的全部接口public Type[] getGenericInterfaces()// 获取父类public Type getGenericSuperclass()
反射源码分析
Method.invoke
@CallerSensitivepublic Object invoke(Object obj, Object... args)throws IllegalAccessException, IllegalArgumentException,InvocationTargetException{if (!override) {if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {Class<?> caller = Reflection.getCallerClass();checkAccess(caller, clazz, obj, modifiers);}}MethodAccessor ma = methodAccessor; // read volatileif (ma == null) {ma = acquireMethodAccessor();}return ma.invoke(obj, args);}//acquireMethodAccessor()private MethodAccessor acquireMethodAccessor() {// First check to see if one has been created yet, and take it// if soMethodAccessor tmp = null;if (root != null) tmp = root.getMethodAccessor();if (tmp != null) {methodAccessor = tmp;} else {// Otherwise fabricate one and propagate it up to the roottmp = reflectionFactory.newMethodAccessor(this);setMethodAccessor(tmp);}return tmp;}public MethodAccessor newMethodAccessor(Method var1) {checkInitted();//MethodAccessor的实现由两种,if走MethodAccessorGenerator,else走NativeMethodAccessorImpl反射次数超过15次则走if分支if (noInflation && !ReflectUtil.isVMAnonymousClass(var1.getDeclaringClass())) {return (new MethodAccessorGenerator()).generateMethod(var1.getDeclaringClass(), var1.getName(),var1.getParameterTypes(), var1.getReturnType(),var1.getExceptionTypes(), var1.getModifiers());} else {//代理模式的实现NativeMethodAccessorImpl var2 = new NativeMethodAccessorImpl(var1);DelegatingMethodAccessorImpl var3 = new DelegatingMethodAccessorImpl(var2);//var2保存var3的引用var2.setParent(var3);return var3;}}
静态代理模式的标准实现
class NativeMethodAccessorImpl extends MethodAccessorImpl {private final Method method;private DelegatingMethodAccessorImpl parent;private int numInvocations;NativeMethodAccessorImpl(Method var1) {this.method = var1;}public Object invoke(Object var1, Object[] var2) throws IllegalArgumentException,InvocationTargetException {if (++this.numInvocations > ReflectionFactory.inflationThreshold() &&!ReflectUtil.isVMAnonymousClass(this.method.getDeclaringClass())) {MethodAccessorImpl var3 = (MethodAccessorImpl)(new MethodAccessorGenerator()). generateMethod(this.method.getDeclaringClass(), this.method.getName(),this.method.getParameterTypes(),this.method.getReturnType(),this.method.getExceptionTypes(),this.method.getModifiers());this.parent.setDelegate(var3);}return invoke0(this.method, var1, var2);}void setParent(DelegatingMethodAccessorImpl var1) {this.parent = var1;}private static native Object invoke0(Method var0, Object var1, Object[] var2);}
class DelegatingMethodAccessorImpl extends MethodAccessorImpl {private MethodAccessorImpl delegate;DelegatingMethodAccessorImpl(MethodAccessorImpl var1) {this.setDelegate(var1);}public Object invoke(Object var1, Object[] var2) throws IllegalArgumentException, InvocationTargetException {return this.delegate.invoke(var1, var2);}void setDelegate(MethodAccessorImpl var1) {this.delegate = var1;}}
NativeMethodAccessorImpl 和DelegatingMethodAccessorImpl继承自同一个类MethodAccessorImpl 。DelegatingMethodAccessorImpl根据传入的MethodAccessorImpl对象来调用其invoke方法。
NativeMethodAccessorImpl.invoke()
public Object invoke(Object var1, Object[] var2) throws IllegalArgumentException,InvocationTargetException {//判断numInvocations的阈值并且不是内部类if (++this.numInvocations > ReflectionFactory.inflationThreshold() &&!ReflectUtil.isVMAnonymousClass(this.method.getDeclaringClass())) {MethodAccessorImpl var3 = (MethodAccessorImpl)(new MethodAccessorGenerator()). generateMethod(this.method.getDeclaringClass(), this.method.getName(),this.method.getParameterTypes(),this.method.getReturnType(),this.method.getExceptionTypes(),this.method.getModifiers());this.parent.setDelegate(var3);}return invoke0(this.method, var1, var2);}
