java为什么存在方法的重载_java – 为什么这个方法重载不明确?

它无法在JDK 1.5,1.6和1.7中编译,但在JDK 1.8中可以编译。

Update: It seems like the fact that it worked with the first JDK8 versions was actually a bug: It worked in JDK 1.8.0_05, but according to 07000 and the answer by medvedev1088, this code will no longer compile in 1.8.0_25, which is the behavior that conforms to the JLS

我不认为这是一个修复的错误。相反,这是与Java 8中的lambda表达式的方法调用机制相关的更改的影响。

大多数人可能会同意关于“方法调用表达式”的部分是Java语言规范中最复杂的不可理解的部分。并且可能有一整队工程师关注交叉检查和验证本节。所以任何陈述或任何尝试的推理都应该用大量的盐。 (即使来自上述工程师)。但是我会试一试,至少梳理出其他人可能提及的相关部分进行进一步分析:

考虑到这一节

并且考虑到这两种方法都是“潜在适用方法”(JLS7/JLS8),则相关小节是关于

对于JLS 7,它规定

The method m is an applicable variable-arity method if and only if all of the following conditions hold:

For 1 = i < n, the type of ei, Ai, can be converted by method invocation conversion to Si.

(其他条件是指在这里不相关的调用形式,例如真正使用varargs的调用或涉及泛型的调用)

参考示例:当b可以通过方法调用转换转换为相应的形式方法参数时,一种方法适用于Byte类型的实际参数表达式b。根据JLS7中有关Method Invocation Conversion的相应部分,允许以下转换:

>身份转换(§5.1.1)

>扩大原始转换(§5.1.2)

>扩展引用转换(§5.1.5)

>拳击转换(§5.1.7),随后加宽参考转换

>拆箱转换(§5.1.8),随后可以加宽原始转换。

显然,根据本规范可以应用两种方法:

> m(数字b,数字… a)适用于扩展参考转换

> m(字节b,数字… a)可通过拆箱转换使用

你提到你“…发现扩大优先级高于拆箱”,但这不适用于:上述条件不涉及任何“优先”。它们被列为不同的选项。即使第一种方法是无效的(Byte b,Number … a),“身份转换”也是适用的,但它仍然只能算作一个可能的转换,并且由于模糊性而导致错误方法。

所以,据我所知,这解释了为什么它不适用于JDK7。我没有弄清楚为什么它与JDK8一起工作。但可变理论方法的适用性定义在Identify Methods Applicable by Variable Arity Invocation in JLS 8年变化不大:

If m is not a generic method, then m is applicable by variable arity invocation if, for 1 ≤ i ≤ k, either ei is compatible in a loose invocation context with Ti or ei is not pertinent to applicability (§15.12.2.2).

(我还没有深入了解“宽松的调用上下文”和第15.12.2.2节的定义,但这似乎是至关重要的区别)

除此之外,再次提及您的声明,您“…发现扩展优先级高于拆箱”:对于不涉及varargs的方法(并且根本不需要方法调用转换),这是正确的。如果您在示例中省略了varags,那么找到匹配方法的过程将从Phase 1: Identify Matching Arity Methods Applicable by Subtyping开始。由于Byte是Number的子类型,因此m(Number b)方法将已经适用于参数Byte b。没有理由进入Phase 2: Identify Matching Arity Methods Applicable by Method Invocation Conversion.在这个阶段,通过从字节到字节的取消装箱方法调用转换将适用,但这个阶段是永远不会达到的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值