2017-02-16 11 views
1

私はJavaの型推論に問題があります。私ではなく、javacのjavacと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); 
    }  
} 

と、EclipseのECJでコンパイルしないのjavac 1.8.0_121、次のコードを使用しています:

[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> 

第二引数なしgmコードは問題なくコンパイルされます。

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) { 
      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を拡張し、何かを返す
  • グラムは、より多く、約推測できるグラムのボディnothingからU.
  • のベース・クラスである何かを受け入れますU.
  • f体から、それはAを返すことを知っているので、A <:Uは真でなければなりません。これは
U.のための潜在的な候補としてAまたはオブジェクトで私たちを残し、この場合、U.:
  • Var.bのでUは<を満たす任意のタイプの可能性があり、U上の任意のより多くの制約を課しません

    コンパイラがgが存在するときにオブジェクトを選択したようだが、gはU.

    については何も追加しませんがmは、単項のときECJは受け入れるとして、これはECJかのjavacで問題である場合、Aは、私も混乱していますコードとjavacはありません。それらのうちの1つだけが正しいことができます。

  • 答えて

    0

    参考文献は見つかりませんでしたが、現在のJava 9アーリーアクセスビルドではエラーなしでコードがコンパイルされます。これからは、ECJではなく、Java 8の問題であると結論づけます。