Java AbstractMethodError 原因分析

Java AbstractMethodError 原因分析背景AbstractMethodError异常对于我来说还是比较不常遇见的,最近有幸遇到,并侥幸的解决了,在这里把此种场景剖析一番,进入正题,下面是AbstractMethodError在Java的异常机制中所处的位置:现在明确了AbstractMethodError所具有的特性:1.它是Error的子类,Error类及其子类都是被划分在非检查异常之列的,就是说这些异常不能在编译阶…

大家好,又见面了,我是你们的朋友全栈君。

背景

AbstractMethodError异常对于我来说还是比较不常遇见的,最近有幸遇到,并侥幸的解决了,在这里把此种场景剖析一番,进入正题,下面是AbstractMethodError在Java的异常机制中所处的位置:

AbstractMethodError类图

现在明确了AbstractMethodError所具有的特性:

1.它是Error的子类,Error类及其子类都是被划分在非检查异常之列的,就是说这些异常不能在编译阶段被检查出来,只能在运行时才会触发。

2.通过API文档里面的解释大致得出的结论就是说A依赖于B,但是执行的时候发现类B的定义发生了改变,这个改变是针对编译的时候发生了改变,也就是说将类A由java文件编译成.class文件的时候用到了类B的class文件,但是在执行的时候JVM发现真正用到的B的class文件和编译的时候用的不是一个了。于是这个异常就被抛了出来。

至此,AbstractMethodError发生的底层原因也了解的差不多了,再往深层的话就是java的编译机制,以及java代码的执行检查这些更靠近虚拟机的东东,那些我也没什么研究,暂且不表。

底层原因了解了,我们继续谈下平常遇到的更直观的场景:

ClassA ->AbstractClassB  ClassA 依赖于AbstractClassB,通常A是我们自己开发的类,而B则是引用的第三方jar包里面的抽象类。我们的项目中又存在AbstractClassB的多个实现版本,比如:1.0,1.2,2.0等版本,通常主版本号发生了改变的话,一般都是不兼容的。

类A

class A {
	B dependency = new BImpl();
	
	public void testMethod(){
		dependency.changedMethodInDifVersion(arg1, arg2);
	}
}

1.0版本的AbstractClassB:

abstract class B {
    // v1.0
    public abstract void changedMethodInDifVersion(int arg1);
}

class BImpl extends B{
    public void changedMethodInDifVersion(int arg1){
        System.out.prinln("我是AbstractClassB 的 1.0 版本实现,Class A编译的时候我没参与,但是Class A运行的时候我却参与了。");        
    }
}

2.0版本的AbstractClassB:

abstract class B {
    //v2.0
    public abstract void changedMethodInDifVersion(int arg1, String arg2);
}

class BImpl extends B{
    public void changedMethodInDifVersion(int arg1, String arg2){
        System.out.prinln("我是AbstractClassB 的 2.0 版本实现,编译的时候是我参与了编译");        
    }
}

 

如果在编译的时候使用的2.0版本中的BImpl和2.0版本的AbstractClassB,然而执行的时候使用的又是1.0版本的BImpl,那么就会抛出AbstractMethodError,这个异常抛出以后会把运行时真正找到的那个方法签名给打印出来的,异常信息会入下:

Exception in Thread XXXXX java.lang.AbstractMehodError  package.Class.运行时实际找到的方法

这个时候在你的classpath中寻找这个类,剔除掉不需要的版本就可以了。

如果在编译的时候使用的2.0版本中的BImpl和2.0版本的AbstractClassB,然而执行的时候使用的又是1.0版本的BImpl 和 1.0版本的AbstractClassB,就会报NoSuchMethodError。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/136925.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • 【Android】Android游戏编程之从零开始[通俗易懂]

    【Android】Android游戏编程之从零开始[通俗易懂]《Android游戏编程之从零开始》主要系统地讲解了Android游戏开发,从最基础部分开始,让零基础的Android初学者也能快速学习和掌握Android游戏开发。《Android游戏编程之从零开始》一共8章,内容包括Android平台介绍与环境搭建、Hello,Android!项目剖析、游戏开发中常用的系统组件、游戏开发基础、游戏开发实战、游戏开发提高篇、Box2d物理引擎、物…

  • hdu 3652 B-number(数字dp)

    hdu 3652 B-number(数字dp)

  • html爱心表白代码(最全)

    html爱心表白代码(最全)代码1:<!DOCTYPEhtml><htmllang=”en”><head><metacharset=”UTF-8″><title>跳动爱心</title><style>*{padding:0;margin:0;}body{background-c

  • 分别以递归调用和迭代的方法求数列_迭代算法和递归算法

    分别以递归调用和迭代的方法求数列_迭代算法和递归算法对于数列,递归和迭代的联系非常紧密。a0,a1,a2,…,an−1,ana_0,a_1,a_2,…,a_{n-1},a_na0​,a1​,a2​,…,an−1​,an​数列就是一串数字,数列来源于生活,有用的数列中蕴含着规则。要完整描述一个数列,方法有二:通项公式an=f(n)a_n=f(n)an​=f(n)递推公式其中通项公式是最一般的情况。由通项公式可以求得任意一…

  • python 递归深度

    python 递归深度python对于递归深度有默认的设置,当递归层数过深,超过1000时,会报错RecursionError:maximumrecursiondepthexceededwhilecallingaPythonobject可以通过如下设置:importsyssys.setrecursionlimit(1200)手动设置递归深度,测试后发现,最大上限在8

  • Zigbee协议栈应用(一)——Zigbee协议栈介绍及简单例子[通俗易懂]

    Zigbee协议栈应用(一)——Zigbee协议栈介绍及简单例子[通俗易懂]1、Zigbee协议栈简介  协议是一系列的通信标准,通信双方需要按照这一标准进行正常的数据发射和接收。协议栈是协议的具体实现形式,通俗讲协议栈就是协议和用户之间的一个接口,开发人员通过使用协议栈来使用这个协议,进而实现无线数据收发。  如图1所示:Zigbee协议分为两部分,IEEE802.15.4定义了PHY(物理层)和MAC(介质访问层)技术规范;Zigbee联盟定义了NWK(网络层)、A…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号