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