我想编写一个具有泛型方法的功能性非泛型接口的实现.实现需要内联闭包和简洁.
作为一个简化的例子
@FunctionalInterface interface Fn {
<R> R fn(R arg);
}
public class Scratch {
Fn id = arg -> arg;
//Fn nul = arg -> null;
//Fn requiresNonNull = ...
}
这使
/Scratch.java:5: error: incompatible types: invalid functional descriptor for lambda expression
Fn id = arg -> arg;
^
method <R>(R)R in interface Fn is generic
where R is a type-variable:
R extends Object declared in method <R>fn(R)
1 error
(实际上,参数将是具有返回类型为R的方法的通用接口.)
是否有一种解决方法而不回到匿名内部类的冗长?
有一个明显相似的问题,“Cannot convert functional interface with generic method into lambda expression”,但这源于使用一个名为Integer的类型参数而不是传统的类似T,而Jon Skeet接受的答案说他不知道我的问题的解决方案.
还有一个长期讨论,“Functional interface confusion”,未能回答这个问题.它不能是“一个冗长的匿名内部类最好在这里”,可以吗?
最佳答案 经过多次实验和间接后,我有一个解决方案.我在命名方面不太成功.
这是个主意
>功能接口和单个抽象方法都没有类型参数.
>功能接口接收具有类型参数但在方法参数中通配符的使用者.
>消费者只是一个内部的gubbins,但它确实有这个类型参数.它用于存储结果,而执行通过封闭函数返回.
>使用者自己接收包含实际业务功能实例的功能接口,该实例具有类型参数化类型.
>有一种将事物联系在一起的默认方法,包括创建消费者.
明确? [修辞]
因此,而不是能够写
Fn id = arg -> arg;
我们至少可以写
Fn id = q -> q.q(arg -> arg);
这是一家lambda lambda工厂.
我们似乎已经没有语法,也无法写出类似的内容
Fn id = Fn.Consumer::q(arg -> arg); // not valid syntax!
总共(主要显示我不作弊)
import java.util.concurrent.atomic.*;
@FunctionalInterface interface Fn {
interface Instance<R> {
R fn(R arg);
}
interface Consumer<R> {
void q(Instance<R> gn);
}
void consume(Consumer<?> consumer);
default <R> R fn(R arg) {
AtomicReference<R> result = new AtomicReference<>();
this.consume((Instance<R> instance) -> { result.set(instance.fn(arg)); });
return result.get();
}
}
public interface Scratch {
Fn id = q -> q.q(arg -> arg);
Fn nul = q -> q.q(arg -> null);
public static void main(String[] args) {
String idStr = id.fn("cruel");
String nulStr = nul.fn("cruel");
System.err.println(idStr);
System.err.println(nulStr);
}
}
我不认为我在类型系统中利用了任何缺乏稳健性.
(我应该在问题中添加一个更复杂的例子来说明你为什么要这样做.)