Java中Method類和invoke方法詳解
在說Method和invoke的使用之前我們來看一個小例子, 如果看懂了那就ok了
public class MethodInvoke {
class Animal {
public void print() {
System.out.println("Animal.print()");
}
}
class Cat extends Animal {
@Override
public void print() {
System.out.println("Cat.print()");
}
}
public static void main(String[] args) throws Exception {
Method animalMethod = Animal.class.getDeclaredMethod("print");
Method catMethod = Cat.class.getDeclaredMethod("print");
Animal animal = new Animal();
Cat cat = new Cat();
animalMethod.invoke(cat); //相當於 cat調用父類的print方法
animalMethod.invoke(animal);//相當於 animal.print();
catMethod.invoke(cat); //相當於 cat.print();
catMethod.invoke(animal);
}
}
執行結果如下
Cat.print()
Animal.print()
Cat.print()
Exception in thread "main" java.lang.IllegalArgumentException: object is not an instance of declaring class
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
代碼中,Cat類覆蓋了父類Animal的print()方法, 然后通過反射分別獲取print()的Method對象。最后分別用Cat和Animal的實例對象去執行print()方法。其中animalMethod.invoke(animal)和catMethod.invoke(cat),示例對象的真實類型和Method的聲明Classs是相同的,按照預期打印結果;animalMethod.invoke(cat)中,由於Cat是Animal的子類,按照多態的特性,子類調用父類的的方法,方法執行時會動態鏈接到子類的實現方法上。因此,這里會調用Cat.print()方法;而catMethod.invoke(animal)中,傳入的參數類型Animal是父類,卻期望調用子類Cat的方法,因此這一次會拋出異常。
Method和invoke源碼解析鏈接:https://blog.csdn.net/wenyuan65/article/details/81145900