2017-08-03 9 views
6

Javaコンパイラが最初のステートメントについて不平を言っているのはなぜですか?式() -> ""には明確な型がないので、Supplier <String>またはカスタム機能のインターフェイスの種類、など...?Java 8型推論エラー、オブジェクト型の変数にラムダ式を代入する

Object emptyStringBuilder =() -> ""; // causes compiler error 

Object emptyStringBuilder = (Supplier<String>)() -> ""; 

正確な原因を詳細に教えてください。

答えて

1

ラムダ式の型推論を使用すると、たとえば、このような何かを書くときつまり、ターゲット・タイプから起こる:

() -> ""; 

確かに(あなたにではなく、コンパイラ)Supplierすなわち、 しかし、私はこのように宣言された型があれば何

static interface Producer<T> { 
    T produce(); 
} 

をこれはあなたのラムダがProducerまたはことができることを意味し。したがって、型の推論が起こるように、割り当ては@FunctionalInterface(またはキャスト)にする必要があります。

+0

ありがとう、私が探していた正確な答え。 – marsouf

3

ラムダ式は@FunctionalInterfaceを実装しています.1つのパブリックな非静的で非デフォルトのメソッドを持つインターフェイスです。最初のケースでは、コンパイラはラムダ式の型を推論することができないので、左側から型を取得します(Object)。コンパイラは、あなたのための任意のインターフェイスを選択しないでください。 Objectは機能インタフェースを実装していないので、コンパイラはこの状況について不平を言います。第2のケースで

あなたは、機能インタフェースSupplier<T>を使用すると、コンパイルの面で正しいObjectに割り当てる - あなたは(その場合にはSupplier<T>)あなたの特定の種類を投げているため、コンパイラはObject最も一般的に満足している(すべてのクラスはObjectクラスから継承します)。

+0

型オブジェクトの変数は、機能的インターフェイスを指すかもしれない - JLSこれらに

ポリ式(ジェネリック、メソッド参照、三項演算子のように、彼らが使用される文脈に依存)として定義されていますか?私は、エラーの原因は、コンパイラは、 "文字列someName()"としてその抽象メソッドの署名を持つ任意の機能的なインターフェイスを指し示すことができる右側の式の正確なタイプを推測することはできないと思いますか? – marsouf

+1

正しい。空のラムダ式は、複数の異なる機能インタフェースで表現される可能性があるため、コンパイラは正確な型を推論できません。静的にコンパイルされた言語としてのJavaは、コンパイルレベルで正確な型を知る必要があり、正しいタイプを選択できません。これは私がそれを理解する方法です。 –