Java 8 lambda和带抽象类的接口扩展

jer*_*ija 11 java lambda spring java-8

假设我想声明Spring RowMapper,但不是创建动态类,而是实现一个实现RowMapper的抽象类.这是我的方法签名:

SqlProcedure#declareRowMapper(RowMapper<?> rowMapper);
Run Code Online (Sandbox Code Playgroud)

CustomRowMapper.java:

public abstract class CustomRowMapper<T> implements RowMapper<T> {
    protected A a = new A();
}
Run Code Online (Sandbox Code Playgroud)

旧的Java方式是写:

sqlProc.declareRowMapper(new CustomRowMapper<Object>() {
    @Override
    public Object mapRow(ResultSet rs, int rowNum) {
        a.doSomething(rs, rowNum);
        return new Object();
    }
});
Run Code Online (Sandbox Code Playgroud)

是否有可能用lambda表达式实现相同的功能?我想做这样的事情:

sqlProc.declareRowMapper((rs, rowNum) -> {
    a.doSomething(rs, rowNum);
    return new Object();
});
Run Code Online (Sandbox Code Playgroud)

但后来我会得到一个编译错误说a cannot be resolved.这是因为Java将此视为该RowMapper#mapRow方法的实现,而不是CustomRowMapper#mapRow.

如何通过lambda表达式告诉Java使用CustomRowMapper而不是RowMapper?这甚至可能吗?

use*_*306 12

Lambdas无法实现抽象类.这就是原因.

本文中提到了一些解决方法,但在尝试引用对象字段时,它不适用于您的情况.除了坚持老式的匿名课程,你能做的就是思考如何将"注入"到lamda,例如:

  • 实例化lambda中的一个对象;
  • 创建lambda范围的一部分;
  • 制作某种单音.


Kon*_*kov 9

您可以扩展功能界面并创建自己的界面:

@FunctionalInterface
public interface CustomRowMapper<T> implements RowMapper<T> {
    static A a = new A();
}
Run Code Online (Sandbox Code Playgroud)

然后,你可以传递一个lambda,这是这样的CustomRowMapper#mapRow()方法的实现:

CustomRowMapper myCustomRowMapperLambda = (rs, rowNum) -> {
    a.doSomething(rs, rowNum);
    return new Object();
};
sqlProc.declareRowMapper(myCustomRowMapperLambda);
Run Code Online (Sandbox Code Playgroud)

  • 请注意,lambda表达式不会*从函数接口继承任何内容.由于`a`是一个`public static`变量,它可能会从lambda表达式的代码中访问,但是它需要被限定为`CustomRowMapper.a`,或者你需要添加`import static CustomRowMapper.a;`来允许不合格的访问.因此将`a`放入`interface`没有任何好处,因为lambda表达式并不比任何其他位置更好,这反过来又使得整个自定义`interface`过时... (4认同)