Reflection is commonly used by programs which require the ability to examine or modify the runtime behavior of applications running in the Java virtual machine. This is a relatively advanced feature and should be used only by developers who have a strong grasp of the fundamentals of the language. With that caveat in mind, reflection is a powerful technique and can enable applications to perform operations which would otherwise be impossible.
Class class1 = Class.forName("reflection.Student"); Constructor[] constructors = class1.getDeclaredConstructors(); for (int i = 0; i < constructors.length; i++) { System.out.println(constructors[i]); }
反射获取类的成员变量
看demo:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
// student 一个私有属性age,一个公有属性email public class Student {
private Integer age;
public String email; }
public class TestReflection { public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException { Class class1 = Class.forName("reflection.Student"); Field email = class1.getField("email"); System.out.println(email); Field age = class1.getField("age"); System.out.println(age); } }
public class TestReflection { public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException { Class class1 = Class.forName("reflection.Student");
Method[] methods = class1.getMethods(); for (int i = 0; i < methods.length; i++) { System.out.println(methods[i]); } } }
public class TestReflection { public static void main(String[] args) throws Exception { Class clazz = Class.forName("reflection.TestReflection"); Method method = clazz.getMethod("target", String.class); method.invoke(null, "666"); }
public static void target(String str) { //打印堆栈信息 new Exception("#" +str).printStackTrace(); System.out.println("invoke target method"); } }
堆栈信息反映出反射调用链路:
1 2 3 4 5 6 7 8
java.lang.Exception: #666 invoke target method at reflection.TestReflection.target(TestReflection.java:17) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at reflection.TestReflection.main(TestReflection.java:11)
invoke方法执行时序图
我们跟着反射链路去看一下源码,先看Method的invoke方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
public 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 volatile if (ma == null) { ma = acquireMethodAccessor(); //获取MethodAccessor } //返回MethodAccessor.invoke return ma.invoke(obj, args); }