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。

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

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

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • AWS EC2文件上传[通俗易懂]

    AWS EC2文件上传[通俗易懂]AWSEC2申请配置、文件上传、nginx安装部署、tomcat安装和项目部署、域名绑定AWSEC2服务器申请配置我这里是参考简书的一篇博客:利用AWS的EC2来搭建属于自己的VPN服务器(MAC平台)在步骤4搭建vpn服务器之前都是可以通用的。非常的详细。文件上传经过以上配置之后应该了解到,使用ssh命令访问aws服务器是会用到其提供的秘钥文件的(我这里是serverK…

    2022年7月20日
    58
  • CreateFileMapping用法

    CreateFileMapping的MSDN翻译和使用心得 测试创建和打开文件映射的时候老是得到”句柄无效”的错误,仔细看了MSDN以后才发觉是函数认识不透,这里把相关的解释翻译出来HANDLECreateFileMapping( HANDLEhFile,                      //物理文件句柄 LPSECURITY_ATTRIBUTESl

    2022年4月6日
    42
  • 御用导航提示页面_终实现微信位置发送到汽车导航 越用越好用

    御用导航提示页面_终实现微信位置发送到汽车导航 越用越好用我们使用微信,其中一个非常好用的功能就是发送位置。在朋友聚会或者去朋友家做客时,只需朋友发送一个微信用微信位置,我们就非常清楚的得知目的地,直接把这个位置推送给手机里的导航软件,并发起导航。然而对于习惯使用中控屏导航的车友来说,这个过程脱节了。微信位置只能使用手机导航,不能直接推送到车载导航。手动输入,无疑更加烦躁,担心输错,还要确认好几次。在最新的高德地图车机版中,我们留意到更新中“手…

    2022年5月30日
    320
  • WebViewJavascriptBridge

    WebViewJavascriptBridgeWeb页面中的JS与iOSNative如何交互?JS和iOSNative就好比两块没有交集的大陆,如果想要使它们相互通信就必须要建立一座“桥梁”。WebViewJavascriptBridge是盛名已久的JSBridge库,它仅使用了少量代码就实现了对于MacOSX的WebView以及iOS平台的UIWebView和WKWebView三种组件的完美支持。WebViewJavascriptBridge主要是作为MacOSX和iOS端(Na.

    2025年8月25日
    3
  • BeanCopier_protobuf的简单使用

    BeanCopier_protobuf的简单使用BeanCopier的简单使用cglib包下的一个类.简单栗子//创建实例.BeanCopiercopier=BeanCopier.create(source.getClass(),target.getClass(),false);//Copy操作copier.copy(person1,person2,null);注意到:第三个参数userConve…

    2025年9月14日
    11
  • 用命令行进入目录_在命令行如何进入子目录

    用命令行进入目录_在命令行如何进入子目录CD命令是更改目录命令如果要进入D盘不用这个命令直接输入D:回车即可要是你非要使用CD命令那要加参数/D你图中输入的CD D:系统只是认为你想在系统中记忆一下D盘所以还是返回原先目录例:D盘下有一个目录叫AD下面还有一个目录叫AE 我想在你图中的位置直接进入AE目录命令如下CD/DD:\AD\AE一定要加参数(/D)如果不加参数只写CDD:\AD\AE系统还是…

    2022年10月15日
    6

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

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