【问题标题】:why does java inference failjava推理为什么会失败
【发布时间】:2016-09-01 11:39:26
【问题描述】:

我有以下看似相似的方法,do1do2

class Demo<A>{
    public <C> Iterable<C> do1(List<? super C> _a) {
        return null;
    }


    public <C extends D, D> Iterable<C> do2(List<D> _a) {
        return null;
    }

    {
        List<? extends A> leA = null;

        do2(leA);
        do1(leA);
    }
}

当我编译上述代码 (javac 1.8.0_92) 时,调用 do2(leA) 有效,而 do1(leA) 失败。

required: List<? super C>
found: List<CAP#1>
reason: cannot infer type-variable(s) C
(argument mismatch; List<CAP#1> cannot be converted to List<? super C>)
where C,A are type-variables:
  C extends Object declared in method <C>do1(List<? super C>)
  A extends Object declared in class Cache
where CAP#1 is a fresh type-variable:
  CAP#1 extends A from capture of ? extends A

现在我想知道:这是由于 javac 中类型推断的实现不完整,还是我使用 do1(leA) 调用创建了无效的类型树?

据我所知:

  • do1(leA): Capture(? extends A) 成为 C 的超类型
  • do2(leA): Capture(? extends A) 成为 C 的超类型(间接通过:Capture(? extends A) == DD :&gt; C

在这两种情况下C 的含义应该(没有错误)解析为"? extends A"

【问题讨论】:

  • 我可以用 JDK 1.8.0_51 重现它。仅供参考,Eclipse Mars.2 编译得很好......
  • 我也可以使用1.8.0_91-b14 编译。 IIRC,更新 40 是错误的 - 这可能是错误之一。也许只是更新你的 java 版本。
  • 感谢up,我更新到1.8.0_92,还是一样的编译错误:pastebin.com/tEUfX2JC
  • @WouterVegter 我在 eclipse mars 上遇到了类似的问题(白色它在 eclipse luna 上工作)。切换到 Mars.2 修复它...我没有时间制定答案并检查我们是否有相同的错误,但您可以与此错误报告进行比较:bugs.eclipse.org/bugs/show_bug.cgi? id=415734

标签: java javac type-inference


【解决方案1】:

你需要extends C 而不是super C

public <C> Iterable<C> do1(List<? extends C> _a) {

C 中的 super 是祖先,而不是子类。

【讨论】:

  • 我也探索了该选项并且可以编译(这将使 do1 中的类型树与 do2 不同)。但我很感兴趣为什么看似相似类型树的方法都不能成功编译..
猜你喜欢
  • 1970-01-01
  • 2014-11-17
  • 2016-04-11
  • 2021-10-10
  • 2013-01-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多