为什么此代码在sourceCompatibility = 1.8时失败 [英] Why does this code fail with sourceCompatibility=1.8

查看:1766
本文介绍了为什么此代码在sourceCompatibility = 1.8时失败的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

  public class Java8Wat {
接口Parcelable {
}

静态类捆绑实现Parcelable {
公共无效投入(Parcelable parcelable){
}

public void put(Serializable serializable){
}

public< T extends Parcelable> T getParcelable(){
return null;



static {
Bundle inBundle = new Bundle();
Bundle outBundle = new Bundle();

outBundle.put(inBundle.getParcelable());
}
}

汇编输出:

  Java8Wat.java:23:错误:对put的引用不明确
outBundle.put(inBundle.getParcelable());
^
将Bundle中的方法put(Parcelable)和方法put(Serializable)放在Bundle中匹配

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



我通过JLS for Java 8浏览了一下,但我没有'

其他观察:如果我将 getParcelable()签名更改为:

  public Parcelable getParcelable()



'p>为什么Java编译器认为放(序列化)来对 outBundle.put可能适用的方法(inBundle.getParcelable( ))调用,应该对Parcelable / Bundle类做什么改变?奖金问题:为什么这个错误只发生在Java 8上,而不发生在Java 7上?

解决方案

改变java 8中的推理方式。 Parcelable 是一个接口。
因此, getParcelable 的传入返回类型会导致模糊调用,因为传入返回类型可以应用于这两种方法。



我主要是指该另一问题为更清楚的解释:为什么这个绑定的泛型方法返回任何类型?



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

The following code works when compiled with sourceCompatibility=1.7 or 1.6, but fails after switching to 1.8:

public class Java8Wat {
  interface Parcelable {
  }

  static class Bundle implements Parcelable {
    public void put(Parcelable parcelable) {
    }

    public void put(Serializable serializable) {
    }

    public <T extends Parcelable> T getParcelable() {
      return null;
    }
  }

  static {
    Bundle inBundle = new Bundle();
    Bundle outBundle = new Bundle();

    outBundle.put(inBundle.getParcelable());
  }
}

Compilation output:

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

Here's the repo with failing code: https://github.com/chalup/java8-wat. Just invoke ./gradlew clean build from project directory.

I skimmed through JLS for Java 8, but I haven't found anything relevant.

Additional observation: the code compiles if I change the getParcelable() signature to:

public Parcelable getParcelable()

Why does java compiler considers put(Serializable) to be potentially applicable method for outBundle.put(inBundle.getParcelable()) call and what changes should be made to Parcelable/Bundle class? Bonus question: why does this error happens only on Java 8 and not on Java 7?

解决方案

I would suggest that this is due to changes in how inference is done in java 8. And to the fact that Parcelable is an interface. Because of this, the infered return type of getParcelable results in an ambiguous call because the infered return type can be applied to both methods.

I would mainly refer to this other question for a clearer explanation : Why can this generic method with a bound return any type?

As of to the real understanding of how the inference works in this specific case and why it is different between java 7 and 8, this would require a deeper study of the inference part of JLS.

这篇关于为什么此代码在sourceCompatibility = 1.8时失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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