假设我想声明Spring的RowMapper
,但不创建动态类,而是实现一个实现RowMapper的抽象类。这是我的方法签名:
SqlProcedure#declareRowMapper(RowMapper<?> rowMapper);
CustomRowMapper.java:
public abstract class CustomRowMapper<T> implements RowMapper<T> {
protected A a = new A();
}
旧的Java方式是写:
sqlProc.declareRowMapper(new CustomRowMapper<Object>() {
@Override
public Object mapRow(ResultSet rs, int rowNum) {
a.doSomething(rs, rowNum);
return new Object();
}
});
是否可以使用lambda表达式实现相同的功能?我想做这样的事情:
sqlProc.declareRowMapper((rs, rowNum) -> {
a.doSomething(rs, rowNum);
return new Object();
});
但是我会收到编译错误a cannot be resolved
。这是因为Java认为这是RowMapper#mapRow
方法的实现,而不是CustomRowMapper#mapRow
。
如何通过lambda表达式告诉Java使用CustomRowMapper而不是RowMapper?这甚至可能吗?
答案 0 :(得分:12)
Lambdas无法实现抽象类。 Here is why
文章中提到了一些解决方法,但在您尝试引用对象字段时,它不适用于您的情况。除了坚持老式的匿名课程,你能做的就是思考如何将“注入”给lamda,例如:
答案 1 :(得分:9)
您可以扩展功能界面并创建自己的界面:
@FunctionalInterface
public interface CustomRowMapper<T> implements RowMapper<T> {
static A a = new A();
}
然后,您可以传递一个lambda,这是CustomRowMapper#mapRow()
方法的实现,如下所示:
CustomRowMapper myCustomRowMapperLambda = (rs, rowNum) -> {
a.doSomething(rs, rowNum);
return new Object();
};
sqlProc.declareRowMapper(myCustomRowMapperLambda);
答案 2 :(得分:3)
这应该有效:
sqlProc.declareRowMapper((rs, rowNum) -> {
new A().doSomething(rs, rowNum);
return new Object();
});
你必须实例化你的对象A.鉴于你所展示的代码,这不会改变一件事。
回答更一般的问题而不仅仅依赖于例子: 即使使用演员你也无法访问私有变量A,我倾向于认为这是由于lamdbas的类型是如何被感染的。
事实上,我认为这并不是一件好事:一个lambda应该是无国籍的。 (你可以使用上下文使其有状态,但这不是我推荐的内容。)