【问题标题】:Different type inference results with javac and ecjjavac 和 ecj 的不同类型推断结果
【发布时间】:2017-07-05 10:01:50
【问题描述】:

我对 Java 的类型推断有疑问。我使用的是 javac 1.8.0_121,下面的代码可以用 Eclipse ECJ 编译,但不能用 javac

import java.util.function.Function;

public class Playbook {

    static class A {
    }

    static class B {
    }

    static class P<T> {
    }

    static class V<T> {  
        static <T, U> V<U> m(P<T> src, Function<? super T, ? extends U> f, Function<? super U, ? extends T> g) {
            return null;
        }

        void b(final P<T> other) {

        }
    }

    public void bindTimeString1(P<A> p1, P<B> p2) {
        V.m(p2, s -> new A(), t -> new B()).b(p1);
    }    
}

用 javac 编译会导致以下错误:

[ERROR] Playbook.java:[31,47] incompatible types: main.java.Playbook.P<main.java.Playbook.A> cannot be converted to main.java.Playbook.P<java.lang.Object>

没有m的第二个参数g,代码编译没有问题:

导入 java.util.function.Function;

public class Playbook {

    static class A {
    }

    static class B {
    }

    static class P<T> {
    }

    static class V<T> {
        static <T, U> V<U> m(P<T> src, Function<? super T, ? extends U> f) {
            return null;
        }

        void b(P<T> other) {

        }
    }

    public void bindTimeString2(P<A> p1, P<B> p2) {
        V.m(p2, s -> new A()).b(p1);
    }
}

我不明白为什么这首先会失败。从代码中,编译器可以推断:

  • f 返回扩展 U 的东西。
  • g 接受 U 的基类。
  • 从 g 的身体中无法推断出更多关于 U 的信息。
  • 从 f 的主体,它知道它返回一个 A,所以 A <: u>
  • Var.b 不再对 U 施加任何约束,因此 U 可以是满足 A <: u a object>

似乎当g存在时编译器选择了Object,但是m是一元时的A,虽然g没有添加任何关于U的东西。

如果这是 ECJ 或 javac 中的问题,我也感到困惑,因为 ECJ 接受代码而 javac 不接受。只有其中一个是正确的。

【问题讨论】:

    标签: java type-inference


    【解决方案1】:

    我没有发现任何参考问题,但是当前的 Java 9 早期访问版本编译代码时没有错误。由此我得出结论,这是 Java 8 中的问题,而不是 ECJ 中的问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-08-03
      • 1970-01-01
      • 2012-06-02
      • 1970-01-01
      • 1970-01-01
      • 2018-09-20
      • 2021-07-05
      相关资源
      最近更新 更多