【发布时间】:2019-10-15 14:03:29
【问题描述】:
我使用 Spring Boot 来编写一个 REST 服务。
当操作成功并相应地失败时,我需要返回一个不同的实体。 Spring 中的ResponseEntity 由T 类型参数化。我知道我可以省略类型并仅返回 ResponseEntity,但是在尝试使用 Java 8 Optional 的 orElse 链创建响应时这还不够:
public ResponseEntity getDashboard(String user, UUID uuid) {
Optional<Dashboard> dashboard = dashboardService.getDashboard( user, uuid );
// this gives unchecked assignment: 'org.springframework.http.ResponseEntity'
// to 'org.springframework.http.ResponseEntity<my.package.SomeClass>'
return dashboard
.map( ResponseEntity::ok )
.orElse( createNotFoundResponse( uuid, "No such object" ) );
}
public static <T> ResponseEntity createNotFoundResp( T entity, String message ) {
ResponseMessage<T> responseMessage = new ResponseMessage<>( message, entity );
return ResponseEntity.status( HttpStatus.NOT_FOUND ).body( responseMessage );
}
由于 Java 编译器的类型推断,orElse 子句应返回与可选项不为空时相同的类型,即ResponseEntity<Dashboard> 而不是ResponseEntity<ResponseMessage>。我试图通过提供不同的返回路径来颠覆这个问题:
if ( dashboard.isPresent() ) {
return ResponseEntity.ok( dashboard.get() );
} else {
return createNotFoundResponse( uuid, "No such object" );
}
...但随后 Intellij 突出显示了 dashboard.isPresent() 部分,并大喊此块可以简化为上面的块(这会导致未经检查的警告)。
有没有办法在没有任何编译器警告和@SuppressUnchecked 注释的情况下干净地编写此代码?
【问题讨论】:
-
在两种方法的签名中添加
<?>到ResponseEntity,导致警告对我来说消失了。 -
"有没有办法在没有任何编译器警告的情况下干净地编写此代码" 是的,使用 if/else。 Intellij 是错误的。 (我的 intellij 不建议“简化”)。
-
@AndyTurner 不同意。
if(x.isPresent() { return f(x.get()); } else {return y;}是一种反模式。return x.map(F:f).orElse(y)是正确的做法。 -
@slim 你只能写如果
f返回x.get()和y的公共超类型。例如,Optional.of("").map(Function.identity()).orElse(new Object())不会编译。 -
@AndyTurner 这是真的,但在极少数情况下,你可以投:
Optional.of("").map(x -> (Object) x).orElse(new Object())
标签: java spring-mvc generics optional