Я не понимаю, почему следующий код не компилируется:
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) в Необязательно не может быть применен к (org.springframework.http.ResponseEntity)
В то время как этот код (который я считаю логически одним и тем же кодом) компилируется:
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.
Я могу заставить его скомпилировать, если я приведу validationErrors к JSendResponse в лямбда-карте, но затем я потеряю некоторые из полей наthe 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));
}
РЕДАКТИРОВАТЬ2: Вот упрощенный пример, который вы можете скопировать / вставить в 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 должны возвращать один и тот же тип, похоже, это связано с параметризацией.Таким образом, map может испускать TypeA, а orElse может испускать TypeB, если это подкласс TypeA.Но они не могут испускать различные параметризованные типы List.List и List , похоже, не считаются подтипами друг друга, и теперь, когда я думаю об этом, они не являются.
ResponseEntity - это другой тип, чем ResponseEntity .Если бы я возвращал обычные JSendResponse и JSendFailResponse из лямбд, это, вероятно, сработало бы.Но я не являюсь, я выпускаю разные версии ResponseEntity, которые на самом деле не связаны иерархией.Так что, я думаю, все сводится к тому, как Optional поддерживает (или не поддерживает) универсальные шаблоны.Я не могу установить тип Необязательного для ResponseEntity, поэтому я ограничен строгими иерархиями типов.
EDIT4:
Приведенный выше пример неверен, поскольку типы переключаются из исходного регистра.Я думаю, что понял, спасибо всем.