Java:方法名称/签名解析是静态完成的(编译时)吗? [英] Java: Is method name/signature resolution done statically (compile-time)?

查看:59
本文介绍了Java:方法名称/签名解析是静态完成的(编译时)吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我今天遇到了一个有趣的问题,我认为这在Java中是不可能的。我针对jgroup的2.6版编译了Java代码,但在运行时使用了2.12版(tomcat Web应用程序部署)。我遇到以下错误

I encountered an interesting problem today which I thought was not possible in Java. I compiled my java code against version 2.6 of jgroups but used version 2.12 at runtime (tomcat web app deployment). I got the following error

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进行编译) ,它工作得很好。

Assuming that the API would have change since then, I thought of porting my code to jgroups-2.12, but to my surprise the code compiled fine with jgroups-2.12 and when I replaced the new jar (without changing a single line in my code, just compiling against jgroups-2.12 instead of jgroups-2.6), it worked perfectly fine.

我后来意识到2.6中的构造函数 Message(Address,Address,Serializable)在2.12中已更改为Message(地址,地址,对象)。这意味着在运行时,JVM试图找到完全相同的方法,但没有成功。

I later realized that the constructor Message(Address, Address, Serializable) in 2.6 was changed to Message(Address, Address, Object) in 2.12. This means at runtime, the JVM was trying to locate the exact same method and was failing to do so.

这是否意味着Java编译器嵌入了确切的方法名称和精确的位置?

Does this mean that Java compiler embeds the exact method name and precise arguments while compiling and a method with broader arguments won't work?

推荐答案

是的,这是正确的-确切的签名已绑定

Yes, that's exactly right - the exact signature is bound at compile-time, and that's what gets included in the bytecode.

实际上,这甚至包括返回类型,对于重载之类的签名不包括该返回类型。

In fact, this even includes the return type, which isn't included in signatures for things like overloading purposes.

从根本上说,如果您更改有关现有公共API成员的任何内容,那将是一个重大突破。您可以摆脱某些仅语言的更改,例如将 String [] 参数更改为 String ... 参数,或引入泛型(在某些情况下,如果擦除与先前的代码兼容,则为 )。

Fundamentally, if you change anything about an existing public API member, that will be a breaking change. You can get away with some language-only changes, such as changing a String[] parameter to a String... parameter, or introducing generics (in some cases, if the erasure is compatible with the previous code), but that's pretty much it.

Java语言规范的第13章都是关于二进制的兼容性-请阅读以获取更多信息。但要特别注意的是,第13.4.14节

Chapter 13 of the Java Language Specification is all about binary compatibility - read that for more information. But in particular, from section 13.4.14:


更改方法或构造函数的形式参数名称不会影响现有的二进制文件。更改方法的名称,方法或构造函数的形式参数的类型,或向方法或构造函数的声明中添加参数或从中删除参数会创建具有新签名的方法或构造器,并且具有以下共同作用:删除具有旧签名的方法或构造函数,并添加具有新签名的方法或构造函数(请参见§13.4.12)。

Changing the name of a formal parameter of a method or constructor does not impact pre-existing binaries. Changing the name of a method, the type of a formal parameter to a method or constructor, or adding a parameter to or deleting a parameter from a method or constructor declaration creates a method or constructor with a new signature, and has the combined effect of deleting the method or constructor with the old signature and adding a method or constructor with the new signature (see §13.4.12).

这篇关于Java:方法名称/签名解析是静态完成的(编译时)吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆