public class Person { private int age; public String name; public Person(){}; public Person(String name) { this.name = name; System.out.println(this.name); } public Person(int age, String name) { this(name); this.age = age; } public int getAge() { return age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public void getInfo() { System.out.println("name:" + name + "; age:" + age); } public void setNum(double x) { x = 3 * x; } public void firstMethod(){ System.out.println("This is first method"); } private void secondMethod(){ System.out.println("This is second method"); } private String ThirdMethod(String arg){ return "This is third method"+arg; } }
public class reflectTest { public static void main(String[] args) throws Exception { //1. 实例化Person Person person = (Person)Class.forName("POJO.Person").newInstance(); //2. getDeclaredMethod()获取方法 Method method = person.getClass().getDeclaredMethod("firstMethod"); //3. method.getModifiers()获取方法做用域,method.getName()获取方法名 System.out.println("fitst method:"+Modifier.toString(method.getModifiers())+" "+method.getName()+" "); //4. invoke注入方法对象 method.invoke(person); } }
执行后输出:java
fitst method:public firstMethod This is first method
依然是看一下源码安全
public Method getDeclaredMethod(String name, Class<?>... parameterTypes) throws NoSuchMethodException, SecurityException { //1.依然是先进行java的安全验证和权限验证,具体参考上一章, //private的方法会抛异常(java.lang.IllegalAccessException) checkMemberAccess(Member.DECLARED, Reflection.getCallerClass(), true); //2.searchMethods将在,privateGetDeclaredMethods返回的方法(Method[])中, //查找一个name(名称),和parameterTypes(参数类型)匹配的方法 Method method = searchMethods(privateGetDeclaredMethods(false), name, parameterTypes); if (method == null) { throw new NoSuchMethodException(getName() + "." + name + argumentTypesToString(parameterTypes)); } return method; }
@CallerSensitive public Object invoke(Object obj, Object... args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException { if (!override) { //1. quickCheckMemberAccess进行权限检查,若是是public,跳出if判断 //若是不是public,则获取这个类(参考上一章),以后对这个类进行判断 if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) { Class<?> caller = Reflection.getCallerClass(); checkAccess(caller, clazz, obj, modifiers); } } //再由MethodAccessor对象来调用invoke方法,具体往下看 MethodAccessor ma = methodAccessor; // read volatile if (ma == null) { ma = acquireMethodAccessor(); } return ma.invoke(obj, args); }
MethodAccessor 是个啥玩意?
我也不知道,源码中也并无写更多注释,但网络上的一篇文章解释了这个对象网络
https://www.sczyh30.com/posts/Java/java-reflection-2/
其中做者解释了使用这个对象的缘由ide每一个Java方法有且只有一个Method对象做为root,它至关于根对象,对用户不可见。当咱们建立Method对象时,咱们代码中得到的Method对象都至关于它的副本(或引用)。root对象持有一个MethodAccessor对象,因此全部获取到的Method对象都共享这一个MethodAccessor对象,所以必须保证它在内存中的可见性。
post
invoke底层会经过jni去调用.dll动态连接库的方法invoke0来实现方法的调用,native实际上是在JVM的栈中找到这个方法,而后经过方法实例根据参数进行方法运行ui