先说结论,Java中的泛型方法无法使用Lambda表达式
做个简单的Demo
首先创建一个存储接口Storable
public interface Storable<T> {
<V,K> T store();
}
其次,创建一个Repository
类,其中的execute
方法将使用到前面的存储接口
public class Repository {
public <T> String execute(Storable<T> storable ){
return "I am storing";
}
}
接下来我们来创建测试类
public class Test {
public static void main(String[] args) {
Repository repository = new Repository();
// 不适用Lambda表达式
System.out.println(repository.execute(new Storable<String>() {
@Override
public <V, K> String store() {
return "I am not Lambda";
}
}));
// 适用Lambda表达式
// 报错,Lambda没办法作用于泛型方法
// System.out.println(repository.execute(() -> {
// return null;
// });
}
在使用Lambda表达式中,报了一个"Target method is generic"的提示。
为什么Lambda表达式没办法使用泛型方法,其实很简单,Lambda表达式是一种函数式编程,作用就是重写接口的唯一方法,也可以看做是声明这个方法,而泛型方法中的类型参数,是在声明方法的时候使用的,而只有在调用方法的时候才确定具体的类型,目前Lambda语法是没办法兼有泛型方法的类型参数,我们来分别看一下两者的声明:
- Lambda表达式语法:
(parameters) -> experssion
或者
(parameters) -> { statements; }
- 泛型方法表达式
public <E,G> void test(Map<E,G> map){ }
官方文档https://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.27.3也提到了
A lambda expression is congruent with a function type if all of the following are true:
- The function type has no type parameters.
如果下面提到的点都能够成立,那么Lambda表达式是能够和一个函数类型相适应的:
- 函数类型不能有类型参数
其实没办法使用Lambda表达式也不是什么大事,直接写该接口的匿名类也可以的。
附上跟舍友聊天的记录,本博客来源是学习Redis中遇到的一个小问题