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的方法,因此这一次会抛出异常。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • 解决启动Azkaban报错问题:java.lang.NoSuchMethodError: com.google.common.collect.ImmutableMap.toImmutableMap

    问题描述: 启动Azkaban报错: java.lang.NoSuchMethodError:com.google.common.collect.ImmutableMap.toImmutableMap 解决方法: 从报错信息来看,是找不到toImmutableMap这个方法.首先找到类ImmutableMap对应的Jar包为guava,然后在服务器查找这个Jar包: find / -name "guava*.jar" 发现除了Azkaban安装目录,其他程序目录下也有guava包.Az

  • 详解java代码中init method和destroy method的三种使用方式

    在java的实际开发过程中,我们可能常常需要使用到init method和destroy method,比如初始化一个对象(bean)后立即初始化(加载)一些数据,在销毁一个对象之前进行垃圾回收等等. 周末对这两个方法进行了一点学习和整理,倒也不是专门为了这两个方法,而是在巩固spring相关知识的时候提到了,然后感觉自己并不是很熟悉这个,便好好的了解一下. 根据特意的去了解后,发现实际上可以有三种方式来实现init method和destroy method. 要用这两个方法,自然先要知道这两

  • 详解Java中Method的Invoke方法

    在写代码的时候,发现从父类class通过getDeclaredMethod获取的Method可以调用子类的对象,而子类改写了这个方法,从子类class通过getDeclaredMethod也能获取到Method,这时去调用父类的对象也会报错.虽然这是很符合多态的现象,也符合java的动态绑定规范,但还是想弄懂java是如何实现的,就学习了下Method的源代码.  Method的invoke方法 1.先检查 AccessibleObject的override属性是否为true. Accessib

  • Java上传文件错误java.lang.NoSuchMethodException的解决办法

    错误详情: java.lang.NoSuchMethodException: [Lorg.springframework.web.multipart.MultipartFile;.<init>() at java.lang.Class.getConstructor0(Unknown Source) at java.lang.Class.getDeclaredConstructor(Unknown Source) at org.springframework.beans.BeanUtils.in

  • java中排序报:Comparison method violates its general contract异常的解决

    前言 上周线上的一段排序的java代码出现了一个Comparison method violates its general contract,在解决这个问题的途中学到了一些知识这里总结分享一下. 异常原因 这个排序导致的异常将会在java7以上的版本出现,所以如果你的JDK从6升级到了7或者8,那一定要小心此异常. 在java7的兼容列表中,就有对此排序不兼容的说明: Area: API: Utilities Synopsis: Updated sort behavior for Arrays

  • java.lang.AbstractMethodError: org.apache.xerces.dom.DocumentImpl.setXmlVersion问题解决方法

    读取本地的xml文件,通过DOM进行解析,DOM解析的特点就是把整个xml文件装载入内存中,形成一颗DOM树形结构,树结构是方便遍历和和操纵. DOM解析的特性就是读取xml文件转换为 dom树形结构,通过节点进行遍历. 这是W3c关于节点的概念 如果xml中包含有大量的数据,由于dom一次性把xml装入内存中的特性,所以dom不适合于包含大量数据的xml解析.当包含有大量xml的时候,用SAX进行解析比较节省内存. 下面是一个运用DOM进行解析xml文件的例子: xml文件结构如下: <?xm

  • Java反射机制及Method.invoke详解

    JAVA反射机制 JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法:这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制. Java反射机制主要提供了以下功能: 在运行时判断任意一个对象所属的类:在运行时构造任意一个类的对象:在运行时判断任意一个类所具有的成员变量和方法:在运行时调用任意一个对象的方法:生成动态代理. 1. 得到某个对象的属性 复制代码 代码如下: public Object get

  • 解决 java.lang.NoSuchMethodError的错误

    解决 java.lang.NoSuchMethodError的错误 1 原因 在项目依赖比较复杂或者 Java 运行的环境有问题时,或者同一类型的 jar 包有不同版本存在,都可能触发该错误.本质上说是 JVM 找不到某个类的特定方法,也就是说 JVM 加载了错误版本的类.说白了,就是 JVM 找不到真正想要调用的方法啦!出现该错误的情形主要有以下两个种: 导入了不匹配的包版本: 开发环境和运行环境不一致. 2 解决方法 查看"External Libraries",看报错的方法到底存

  • 解析Java中的Field类和Method类

    Field类 Field类中定义了一些方法,可以用来查询字段的类型以及设置或读取字段的值.将这些方法与继承而来的member方法结合在一起.就可以使我们能够找出有关字段声明的全部信息,并且能够操纵某个特定对象或类的字段. getGenericType方法返回表示字段的声明类型的Type实例.对于像String或int这样的平凡类型,该方法将返回与其相关联的Class对象,例如String.class和int.classo对于像List < Stri ng>这样的参数化类型,该方法将返回Para

  • java中Class.getMethods()和Class.getDeclaredMethods()方法的区别

    在java中,可以根据Class类的对象,知道某个类(接口)的一些属性(成员 ,方法,注释,注解)等.由于最近的工作中用到了这些,其中需要在代码中格局反射知道某些类的方法,查看文档的时候,看到了getMethods()和getDeclaredMethods()的差异.虽然两者都能实现目的,但个人觉得还是有必要区分下. JDK API(1.6)文档中是这样翻译两个方法的: getMethods(): 返回一个包含某些 Method 对象的数组,这些对象反映此 Class 对象所表示的类或接口(包括

随机推荐