Java反射之Method.invoke()的使用
在实习的过程中看到了项目中多次用到了反射,并且是method.invoke()的使用,便自己尝试一下。
- 首先创建三个类,一个Animal,一个Cat一个Dog分别继承Animal
// 父类
public class Animal {
public void call(String name){
System.out.println(name +"这是动物的叫声");
}
}
// 子类
public class Cat extends Animal {
@Override
public void call(String name) {
System.out.println(name + "喵喵喵~~~~");
}
}
// 子类
public class Dog extends Animal {
@Override
public void call(String name) {
System.out.println(name + "汪汪汪~~~");
}
}
- 在客户端中我们做如下尝试:
尝试一
public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
Class<Animal> animalClass = Animal.class; // 类型类是父类
Method call = animalClass.getDeclaredMethod("call",String.class);// 获得里面的call方法
Cat cat = new Cat();
call.invoke(cat,"achao"); // 传入Cat实例
}
// 执行结果
// achao喵喵喵~~~~
当然,我们在method.invoke()中传递一个dog的实例时,执行的是dog中的方法。
尝试二
public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
Class<Cat> catClass = Cat.class;// 类型类是Cat
Method call = catClass.getDeclaredMethod("call",String.class);
Cat cat = new Cat();
call.invoke(cat,"achao"); // 传入Cat实例
}
// 结果是显然的,执行的是“achao喵喵喵~~~~”
尝试三
public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
Class<Cat> catClass = Cat.class;// 类型类是Cat
Method call = catClass.getDeclaredMethod("call",String.class);
Animal animal = new Animal();
call.invoke(animal,"achao");// 传入Animal实例
}
// 结果是报错:java.lang.IllegalArgumentException:
尝试到这里我们可以猜想,当我们的类型类对象是一个子类的时候,我们想传递一个父类去执行里面具体的方法(先不管具体执行的是谁的方法),我们常规的想法是总会执行成功一个方法吧,但是,结果就是报错了。
所以我得出结论:
当通过某个类反射得到的method对象,使用method.invoke()执行某个实例的时候,这个实例 instance of 这个类必须是true,否则报错;如果这个实例重写了这个类的方法,则执行这个实例所对应的方法;如果没有,还是执行这个类的方法。