我不明白为什么以下代码无法编译:
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));
}
编译错误:
或其他 (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的子类,最终返回该子类。似乎lambda代码无法理解JSendFailResponse是JSendResponse。
如果将validationErrors强制转换为地图lambda中的JSendResponse,则可以编译它,但是随后我丢失了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());
所以问题似乎不是map和orElse必须返回相同的类型,这似乎与参数化有关。因此,如果map是TypeA的子类,则map可以发出TypeA,orElse可以发出TypeB。但是它们不能发出不同的List参数化类型。 List
ResponseEntity
EDIT4:
上面的示例是错误的,因为类型是从原始大小写切换的。我想我现在明白了,谢谢大家。
答案 0 :(得分:6)
从map()
发出的类型被推断为JSendFailResponse
,但是您在orElse()
中提供了另一种类型,并且两种类型必须一致。
明确键入以使用常见类型呼叫map()
:
.<JSendResponse>map(validationErrors -> new ResponseEntity<>(validationErrors, HttpStatus.BAD_REQUEST))
答案 1 :(得分:1)
如果您检查oracle文档:https://docs.oracle.com/javase/8/docs/api/java/util/Optional.html,
.ofNullable()
方法的签名为:public static <T> Optional<T> ofNullable(T value)
和orElse()
:public T orElse(T other)
因此,这两种方法类型上的参数均为T
,而orElse()
上没有<? extends T>
作为参数,它们两者都应具有T
作为类型,因此您的方法不应我猜工作,
您应该尝试以下操作(使用简化示例):
public List<TypeA> getList(TypeA ta) {
ArrayList<TypeA> typeAinstance = new ArrayList<>();
return Optional.ofNullable(ta)
.map(a -> new ArrayList<TypeA>(Arrays.asList(a)))
.orElse(typeAinstance.getClass().cast(Arrays.asList(new TypeB())));
}
public class TypeA {
}
public class TypeB extends TypeA {
}
希望这会有所帮助