为什么此代码因sourceCompatibility = 1.8而失败

使用sourceCompatibility = 1.7或1.6编译时,以下代码有效,但切换到1.8后失败:

public class Java8Wat { interface Parcelable { } static class Bundle implements Parcelable { public void put(Parcelable parcelable) { } public void put(Serializable serializable) { } public  T getParcelable() { return null; } } static { Bundle inBundle = new Bundle(); Bundle outBundle = new Bundle(); outBundle.put(inBundle.getParcelable()); } } 

编译输出:

 Java8Wat.java:23: error: reference to put is ambiguous outBundle.put(inBundle.getParcelable()); ^ both method put(Parcelable) in Bundle and method put(Serializable) in Bundle match 

这是代码失败的回购: https : //github.com/chalup/java8-wat 。 只需从项目目录中调用./gradlew clean build

我浏览了JLS for Java 8,但我没有发现任何相关内容。

附加观察:如果我将getParcelable()签名更改为getParcelable()代码,则编译代码:

 public Parcelable getParcelable() 

为什么java编译器认为put(Serializable)outBundle.put(inBundle.getParcelable())调用的潜在适用方法, outBundle.put(inBundle.getParcelable())outBundle.put(inBundle.getParcelable()) / Bundle类进行哪些更改? 奖金问题:为什么这个错误只发生在Java 8上,而不发生在Java 7上?

我建议这是由于在Java 8中如何进行推理的变化以及Parcelable是一个接口这一事实。 因此, getParcelable的不getParcelable返回类型getParcelable导致模糊调用,因为可以将getParcelable返回类型应用于这两种方法。

我将主要参考另一个问题以获得更清楚的解释: 为什么这个带有绑定的generics方法可以返回任何类型?

至于真正理解推理如何在这个特定情况下工作以及为什么它在java 7和8之间有所不同,这需要对JLS的推理部分进行更深入的研究。

正如消息所说, reference to put is ambiguousreference to put is ambiguous

您必须探索强制转换值,以便编译器知道您要使用的方法:

 outBundle.put((Parcelable)Bundle.getParcelable()); 

要么

 outBundle.put((Serializable)Bundle.getParcelable());