Javaの8ラムダおよびオプションでサブクラス

JCN:

次のコードはコンパイルされませんなぜ私は理解していません。

private ResponseEntity<JSendResponse> buildResponse(RequestModel requestModel,
                                                    RequestModelParamConverter paramConverter,
                                                    Supplier<String> xsdSupplier,
                                                    Supplier<String> xmlTemplateSupplier) {

    return Optional.ofNullable(new RequestErrorHandler<>().validate(validator, requestModel))
            .map(validationErrors -> new ResponseEntity<>(validationErrors, HttpStatus.BAD_REQUEST))
            .orElse(this.buildResponseForValidRequest(requestModel, paramConverter, xsdSupplier, xmlTemplateSupplier));
}

コンパイルエラー:

オプションでorElseは(org.springframework.http.ResponseEntity <com.company.util.response.JSendFailResponse>)(org.springframework.http.ResponseEntity <com.company.util.response.JSendResponse>)に適用することはできません

(私は同じコードが論理的だと思います)、このコードはコンパイルんが:

private ResponseEntity<JSendResponse> buildResponse(RequestModel requestModel,
                                                    RequestModelParamConverter paramConverter,
                                                    Supplier<String> xsdSupplier,
                                                    Supplier<String> xmlTemplateSupplier) {

    JSendResponse validationErrors = new RequestErrorHandler<>().validate(validator, requestModel);

    if(validationErrors == null) {
        return this.buildResponseForValidRequest(requestModel, paramConverter, xsdSupplier, xmlTemplateSupplier);
    }
    else
    {
        return new ResponseEntity<>(validationErrors, HttpStatus.BAD_REQUEST);
    }
}

問題は)RequestErrorHandler <>(ということのようです。validateメソッド検証が失敗した場合にJSendFailResponseというクラスを返します。JSendFailResponseは、最終的に返されるものですJSendResponse、のサブクラスです。ラムダコードがJSendFailResponseがJSendResponseであることを理解することができないように思えます。

私は、マップラムダにJSendResponseにによりvalidationErrorsをキャストする場合、私はそれをコンパイルするために取得することができますが、その後、私はJSendFailResponse上のフィールドの一部を失います。

編集:このコードもコンパイルに失敗します。

private ResponseEntity<? extends JSendResponse> buildResponse(RequestModel requestModel,
                                                    RequestModelParamConverter paramConverter,
                                                    Supplier<String> xsdSupplier,
                                                    Supplier<String> xmlTemplateSupplier) {

    return Optional.ofNullable(new RequestErrorHandler<>().validate(validator, requestModel))
            .map(validationErrors -> new ResponseEntity<>(validationErrors, HttpStatus.BAD_REQUEST))
            .orElse(this.buildResponseForValidRequest(requestModel, paramConverter, xsdSupplier, xmlTemplateSupplier));
}

EDIT2:ここではあなたがあなた自身のために見るためにあなたのIDEにコピー/ペーストすることができます簡単な例です。

import java.util.*;

public class GemLamDemo {

    public static void main(String... args) {

        GemLamDemo gld = new GemLamDemo();

        gld.getList(null);

    }

    public List<? extends TypeA> getList(TypeA ta) {

        return Optional.ofNullable(ta)
                .map(a -> new ArrayList<TypeA>(Arrays.asList(a)))
                .orElse(new ArrayList<TypeB>(Arrays.asList(new TypeB())));
    }

    public class TypeA {

    }

    public class TypeB extends TypeA {

    }
}

EDIT3:私は、私がこれまでに受け取った援助に基づいて、この問題を理解して考えますが、次のコードのコンパイルと作品ました。

Optional.ofNullable(val1)
                .map(a -> new TypeA())
                .orElse(new TypeB());

問題はマップとorElseは同じ型を返さなければならないということではないようですので、paramterizationに関連しているようです。だから、マップは、タイプAを発することができるし、タイプAのそのサブクラスであればorElseはタイプBを発することができます。しかし、彼らはリストのパラメータ化された型が異なる放出することはできません。一覧<タイプA>とListは、<Bタイプ>お互いのサブタイプを考慮されていないようですし、今私はそれについて考える、そうではありません。

ResponseEntity <JSendResponse> ResponseEntity <JSendFailResponse>とは異なるタイプです。私はラムダからプレーンJSendResponseとJSendFailResponseを返却していた場合、それはおそらく仕事だろう。しかし、私は本当に階層によって関連していないResponseEntityの異なるバージョンを、発光よ、ないんだけど。私が推測するように、それがどのように任意の支持体にダウンしています(またはサポートしていません)ワイルドカードジェネリックを。私は<ResponseEntityにオプションの種類を設定することはできませんか?JSendResponseを拡張>ので、私は厳密な型階層に制限されています。

EDIT4:

タイプは、元のケースから切り替えられるため、上記の例が正しくありません。私は、今のおかげで誰もがそれを得ると思います。

ボヘミアン:

放出されたタイプがmap()のように推測されJSendFailResponseていますが、中に異なる種類を提供しているorElse()と、両方のタイプが同意しなければなりません。

明示的に呼び出すように入力しmap()、共通のタイプ:

.<JSendResponse>map(validationErrors -> new ResponseEntity<>(validationErrors, HttpStatus.BAD_REQUEST))

おすすめ

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