ジェネリック医薬品とのVavrは、互換性のない型を与えます

オパール:

誰が、なぜこのコードを説明してくださいでした:

interface Lol {
  default Try<Seq<? extends Number>> lol() {
    return Try.of(List::empty);
  }
}

class LolImpl implements Lol {
  @Override
  public Try<Seq<? extends Number>> lol() {
    return Try
      .of(() -> List.of(1, 2, 3))
      //.onFailure(Object::hashCode)
      ;
  }
}

私のコメントを外した場合、コンパイルに失敗したonFailureステートメントの?ここでは何が起こるか全くわかりません。どのようにそれを改善するには?

サイモンStepniak:

あなたは呼び出すことができTry.of()、コンパイラのチェックを満たすために返された明示的なジェネリック型で。何かのようなもの:

Try.<Seq<? extends Number>of(() -> List.of(1,2,3))

Try.of()戻りタイプTry<T>どこTサプライヤーによって返されたタイプです。そしてのでList.of(T t...)戻りList<T>、その後、コンパイラによって見られ、最終的なタイプがあるTry<List<Integer>メソッド返される型が定義されて何をされていません、。特定のタイプを持つJavaのジェネリックは不変であり、彼らはそう、共変または反変の置換をサポートしていませんList<Integer> != List<Number>

作業例:

import io.vavr.collection.List;
import io.vavr.collection.Seq;
import io.vavr.control.Try;

interface Lol {
    default Try<Seq<? extends Number>> lol() {
        return Try.of(List::empty);
    }
}

class LolImpl implements Lol {
    @Override
    public Try<Seq<? extends Number>> lol() {
        return Try
                .<Seq<? extends Number>>of(() -> List.of(1, 2, 3))
                .onFailure(t -> System.out.println(t.getMessage()));

    }

    public static void main(String[] args) {
        System.out.println(new LolImpl().lol());
    }
}

出力:

Success(List(1, 2, 3))

一般的な例型推論の問題

詳しい調査の結果、これはおそらく、一般的なコンパイラの問題であることを示します。以下の単純なJavaの例を見てみましょう:

import java.util.Arrays;
import java.util.List;
import java.util.function.Supplier;

interface Some<T> {
    static <T> Some<T> of(Supplier<T> supplier) {
        return new SomeImpl<>(supplier.get());
    }

    default Some<T> shout() {
        System.out.println(this);
        return this;
    }

    class SomeImpl<T> implements Some<T> {
        private final T value;

        public SomeImpl(T value) {
            this.value = value;
        }
    }

    static void main(String[] args) {
        final Some<List<CharSequence>> strings = Some.of(() -> Arrays.asList("a", "b", "c"));
    }
}

すべての問題とコンパイラ推論せずにこのコードをコンパイルは、によって返される型Arrays.asList()左側に期待タイプから:

ここでは、画像の説明を入力します。

さて、私はこれを呼び出した場合Some<T>.shout()は何も戻りません方法、Some<T>コンパイラ推論をしませ予想変数の型から、しかし最後の返されたタイプからタイプ:

ここでは、画像の説明を入力します。

コースのArrays.asList("a","b","c")リターンList<String>this is the type叫ぶ() `メソッドの推論とリターン:

ここでは、画像の説明を入力します。

明示的な型指定Some<T>.of()のように解きに問題をTry.of()例:

ここでは、画像の説明を入力します。

私は、型推論にOracleのドキュメントを検索し、この説明があります:

Javaコンパイラは、ジェネリックメソッド呼び出しの型パラメータを推測するために、ターゲットタイピングを利用しています。式のターゲット・タイプは、Javaコンパイラを期待式が表示される場所に応じて、そのデータ型です。

出典:https://docs.oracle.com/javase/tutorial/java/generics/genTypeInference.html#target_types

それはこのようになります「という表現が表示される場所に応じて、」このような場合には手段は、以前に返された正確なタイプからタイプを推論しました。スキップなぜそれが説明するだろうshout()方法は、コンパイラが認識します、我々は期待していること、Some<List<CharSequence>>そして私たちが追加するときshout()の方法を、それが戻って開始しSome<List<String>>、これは何であるので、shout()この方法は、の戻りタイプから見ているSome.of()方法。それが役に立てば幸い。

おすすめ

転載: http://43.154.161.224:23101/article/api/json?id=172480&siteId=1