2017-03-21 4 views
5

に適用されます:型推論はこれが<a href="https://docs.oracle.com/javase/tutorial/java/generics/genTypeInference.html" rel="noreferrer">Java Tutorials</a>は、型推論を定義する方法であるJavaの非ジェネリック

型推論はタイプ 引数を(決定するために、各メソッド 呼び出しと対応する宣言を見てJavaコンパイラの能力ですか引数)を使用して呼び出しを適用します。 推論アルゴリズムは、引数のタイプを決定し、 が利用可能であれば、結果が割り当てられるか返されるタイプを決定します。 最後に、推論アルゴリズムは、すべての引数で機能するもっとも特殊なタイプの を見つけようとします。

以下、ジェネリックスのすべての例を使用して型推論を説明します。

私の質問は次のとおりです。Javaの型推論は、ジェネリックがプレイに参加したときにのみ適用されますか?そうでない場合は、1つまたは2つの例が参考になります。

+0

興味深い質問です。しかし、私はアルゴリズムがJavaのクラスの多態性のために毎回使われていると思います。 – KarelG

答えて

2

lambdasでは、引数の型を指定する必要はなく、型も返されるため、自動的に導かれます。たとえば:

listOfStrings.stream(). 
     map((aString) -> { 
       //do something 
      anObject anobject = new anObject(); 
      return anobject;}) 

     .collect(Collectors.toList()); 

返されるリストのタイプはList<anObject>ある、と私はそれがlistOfStringsタイプによってinferedされるようaStringのはString型であることを指定する必要はありませんでした。

1

私の最初の考えは「必ずしも必要ではありません。 foo(long)とfoo(double)のどちらをfoo(int)とfoo(double)のどちらが呼び出されるべきかを理解するのと同じように、オーバーロードが発生したときに一致するメソッドを選択するためにメソッド引数を解析する必要があったからです。

しかし、よく、これは約ターミノロジーです。正しいオーバーロードされたメソッドを検出するために「ある計算」が必要であるという事実は、「Javaの父親」がこれらの計算が「型推論」の原因であると考えるわけではありません。

これとは逆に、Java言語仕様は、全体についての章がtype inferenceです。それを綿密に調べると、ジェネリック型とラムダについては「唯一の」ものです。

答えは次のようになります。Java人がその用語を使用しているのは、generics/lambdasのみです。引数型を分析する必要がある他の状況については考慮しません。

+0

親愛なるdownvoter:コメントが役に立ちます。 – GhostCat

+0

メソッドのオーバーロードには型参照が必要なので、受け入れることができるようにしてください。 –

+0

私はやったが、他の答えが与える結論にもっと来る。 – GhostCat

1

本当の非ジェネリック環境で型推論をするのはあまり意味がありません。そうしないと、あなたとコンパイラは型をすでに知っていて、コンパイラが何かを干渉する必要はないからです。 しかし、私が見つけることができる終了例は約Target Typesです。ドキュメントから

この

void processStringList(List<String> stringList) { 
    // process stringList 
} 

として宣言されている方法を取ると、何のターゲットが指定されていない場合、それはスローされます、あなたはList<Objectを返してCollections.emptyList()ので、この

processStringList(Collections.emptyList()); 

でそれを呼び出しますエラー

List<Object> cannot be converted to List<String> 

ここでコンパイラはablではありませんeを入力してList<>の型引数を干渉させます。

processStringList(Collections.<String>emptyList()); 

などのターゲットタイプを明示的に指定する必要がありますが、それ以上は必要ではありません。 Oracle docs Type Inference

これはもはや必要なJava SE 8ターゲット・タイプは、このような方法のprocessStringListへの引数としてメソッドの引数を含むように拡張されたものであるという概念ではありません。この場合、processStringListにはList型の引数が必要です。メソッドCollections.emptyListはListの値を返します。したがって、ターゲット型のListを使用すると、コンパイラは型引数Tの値がStringであることを推測します。このように、JavaのSE 8で、次の文は、コンパイルされます。

だから、最後の例では、コンパイラはCollections.emptyList()からList<String>を取得するための型引数を妨げます。

+0

タイプ推論では、ターゲットタイプを使用します。ターゲットタイプは、タイプ推論の有効な例ではありません。 '推論アルゴリズムは、呼び出し引数、ターゲット型、およびおそらく型を推測する明白な期待戻り型のみを使用します.' https://docs.oracle.com/javase/tutorial/java/generics/genTypeInference.html –