显式转换导致NoSuchMethodError?

时间:2011-11-10 15:14:54

标签: java

我试图弄清楚为什么我的两个Java库难以一起玩。这是场景:

库1有一个带有以下构造函数的类A:

public A(Object obj) { /* boilerplate */ }

在以前的版本中,A的构造函数是:

public A(Serializable s) { /* more or less same boilerplate */ }

现在,库2是针对先前版本构建的,并构造了A:

的实例
A myObject = new A( (Serializable) arg);

当库1(最新版本)和2一起部署时,构造函数调用抛出NoSuchMethodError,并且堆栈跟踪解释了JVM正在寻找具有Seri​​alizable参数的构造函数。

在我看来,所有对象实例都可以转换为Object,即使在调用期间显式转换为接口也是如此。然而,这个实验已经证实了。对于后代,任何人都可以详细说明Java的哪些规则导致NoSuchMethodError出现?我非常感谢规范引用。

2 个答案:

答案 0 :(得分:6)

编译库2时解析new A(...)调用的方法,并将其签名存储在库2的类文件中。

如果针对旧版本的库1编译库2,A myObject = new A( (Serializable) arg)的字节码应如下所示:

   9:   new #1;     //class A
   12:  aload_1     //arg
   13:  invokespecial   #24; //Method "<init>":(Ljava/io/Serializable;)V

如果调用此代码时不再存在带有此签名的方法,则会得到NoSuchMethodError

答案 1 :(得分:1)

构造函数在编译时被重载(未被覆盖)并受限制。

所以lib2正在寻找A(Serializable),但只有A(对象)。