今天我遇到了一个有趣的问题,我认为这在 Java 中是不可能的。我针对 jgroups 2.6 版本编译了 java 代码,但在运行时使用了 2.12 版本(tomcat Web 应用程序部署)。我收到以下错误
org.jgroups.Message.<init>(Lorg/jgroups/Address;Lorg/jgroups/Address;Ljava/io/Serializable;)
假设 API 从那时起会发生变化,我想将我的代码移植到 jgroups-2.12,但令我惊讶的是,代码用 jgroups-2.12 编译得很好,当我替换新的 jar 时(没有更改代码中的一行,只是针对 jgroups-2.12 而不是 jgroups-2.6 进行编译),它工作得很好。
后来我意识到构造函数Message(Address, Address, Serializable)
2.6中的2.12中更改为消息(地址,地址,对象)。这意味着在运行时,JVM 试图找到完全相同的方法,但未能成功。
这是否意味着 Java 编译器在编译时嵌入了精确的方法名称和精确的参数,而具有更广泛参数的方法将不起作用?
是的,这是完全正确的 - 确切的签名是在编译时绑定的,这就是字节码中包含的内容。
事实上,这甚至包括返回类型,它不包含在用于重载目的的签名中。
从根本上讲,如果您对现有公共 API 成员进行任何更改,这将是一个重大更改。您可以进行一些仅针对语言的更改,例如更改String[]
参数aString...
参数,或引入泛型(在some情况下,如果擦除与之前的代码兼容),但仅此而已。
第13章 http://java.sun.com/docs/books/jls/third_edition/html/binaryComp.htmlJava 语言规范的全部内容都是关于二进制兼容性 - 阅读该规范以获取更多信息。但特别是,从第13.4.14节 http://java.sun.com/docs/books/jls/third_edition/html/binaryComp.html#13.4.14:
更改方法或构造函数的形式参数名称不会影响预先存在的二进制文件。更改方法的名称、方法或构造函数的形参类型,或者在方法或构造函数声明中添加参数或删除参数,都会创建具有新签名的方法或构造函数,并具有以下综合效果:删除具有旧签名的方法或构造函数并添加具有新签名的方法或构造函数(请参阅§13.4.12)。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)