java - 将泛型类型参数标记为 Java 8 中的功能接口(interface)

标签 java generics lambda java-8 java-stream

我想将函数的类型参数限制为函数式接口(interface)。

像这样:

public static <@FunctionalInterface T extends Function<A, B>> T foo () {
    return a -> bar;
}

此处不允许使用@FunctionalInterface

目的是使返回具有类型参数类型的 lambda 成为可能。由于 T 可以是普通类,因此不允许返回 lambda。

是否可以将类型参数限制为功能接口(interface)?

最佳答案

正如在 your other question 上讨论过的那样不可能那样做。不仅注释类型参数,而且特别是通过 lambda 表达式实现未知接口(interface)。

编译你的方法时

public static <@FunctionalInterface T extends Function<A, B>> T foo() {
    return a -> bar;
}

编译器必须生成能够返回适当类型实例的代码,但它不知道 T 是什么,因为这取决于 foo() 的调用者> 但是编译 foo() 和编译 foo() 的调用者之间没有联系。后者可能会在数年后发生在地球的另一边。

也许你不知道Type Erasure .您的方法 foo() 将只有一个编译版本,但它必须满足返回适当类型实例的通用契约。 不知道 T 是什么

这在返回现有实例时有效,例如在返回集合元素或作为参数传递的值之一时。但是泛型方法无法返回类型参数的新实例。不使用 new 也不使用 lambda 表达式。


请注意,如果您让知道类型的调用者执行“上层”操作,则仍然可以实现所需功能的子接口(interface)。假设您有一个通用工厂方法,例如:

public static <A,B> Function<A,B> getter(Map<?, ? extends B> map) {
    return a->map.get(a);
}

此代码适用于未知类型 AB 以及 Map 的未知参数化,因为唯一的约束是方法 Map.get 接受 A 的实例,它接受 anything 并返回 B 的实例,它像 any输入? extends B 将分配给 B

现在,如果您的调用者具有 Function 的任意子类型,X,例如

interface X extends Function<String, Integer> {}

它可以使用您的工厂方法生成 X 的实例,装饰 函数,例如:

Map<String, Integer> map=new HashMap<>();
X x=getter(map)::apply;
x.apply("foo");

在这里,X 是一个函数式接口(interface) 的约束在调用方站点上被检查。

关于java - 将泛型类型参数标记为 Java 8 中的功能接口(interface),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24382343/

相关文章:

java - 存储和管理(正确反序列化对象以及反序列化后如何使用它们

Java,Mysql-列名标识为变量

java - 为什么 toArray 的 <T> 隐藏了 Collection<E> 的 <E>?

c++ - std::visit无法识别类型

C++11 lambdas 和方括号

java - Android - Java - 正则表达式问题 - 连续单词不匹配

java - Java 中的 C 词法解析器源代码

java - gemfire 教程中的泛型用法

asp.net - MVC 通用 ViewModel

variables - 为什么不能像Java中那样在内联函数中正确初始化变量?