我正在尝试为我在 play 框架(2.5.4)中开发的应用程序实现一个非阻塞 DAO 层。它在deleteById()中给了我错误
no instance(s) of variable(s) U exists so that void conforms to U
abstract class BaseDao<E extends BaseModel> {
JPAApi jpaApi;
private Class<E> entityClazz;
BaseDao(JPAApi jpaApi, Class<E> entityClazz) {
this.jpaApi = jpaApi;
this.entityClazz = entityClazz;
}
public CompletionStage<E> save(E entity) {
return CompletableFuture.supplyAsync(() -> {
jpaApi.em().persist(entity);
return entity;
});
}
public CompletionStage<Optional<E>> findById(String id) {
return CompletableFuture.supplyAsync(() -> Optional.ofNullable(jpaApi.em().find(entityClazz, id))
);
}
public void deleteById(String id) {
findById(id).thenApply(
result -> result.ifPresent(
//HERE IS WHERE MY IDE COMPLAINTS
entity -> {
entity.setActive(false);
save(entity);
}
)
);
}
}
如有任何帮助或建议,我们将不胜感激。
最佳答案
只是为了理解为什么会出现错误
-
Optional.ifPresent()
接受一个 Consumer,返回void
-
CompletionStage.thenApply()
需要Function<T, U>
。返回类型U
必须与 lambda 主体的返回类型匹配 - 在本例中Optional.ifPresent()
. -
void
是一个原始类型并且没有盒装的等效类型,因此编译器被难住了。
您可以做的一件事是将表达式 lambda 转换为返回某种值的 block lambda。 例如
findById(id).thenApply(
result -> {
result.ifPresent(
entity -> {
entity.setActive(false);
save(entity);
}
);
return 1;
}
);
这应该允许编译器将类型绑定(bind)在一起 - thenApply()
将采取 Function
返回 Integer
,而ifPresent()
仍然可以拿Consumer
返回无效。
或者,也许更好的是,您可以使用 thenAccept()
方法CompletionStage()
,它接受 Consumer
而不是Function
...
findById(id).thenAccept(
result -> result.ifPresent(
entity -> {
entity.setActive(false);
save(entity);
}
)
);
关于Java 泛型 Lambda 编译错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38368459/