2 回答
TA贡献1796条经验 获得超7个赞
泛型 lambda 不合法,但泛型方法引用是合法的。您可以通过创建辅助方法来减少匿名类的冗长:
public class Scratch {
Fn id = Scratch::id;
Fn nul = Scratch::nul;
Fn requiresNotNull = Objects::requireNonNull;
private static <R> R id(R arg) {
return arg;
}
private static <R> R nul(R arg) {
return null;
}
}
TA贡献1785条经验 获得超8个赞
经过大量实验和间接操作后,我有了一个解决方案。我在命名方面不太成功。
这是想法
函数式接口和单个抽象方法都没有类型参数。
函数式接口接收具有类型参数但在方法参数中使用通配符的使用者。
消费者只是一块内部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);
}
}
我认为我没有利用类型系统中的任何缺陷。
(我可能应该在问题中添加一个更复杂的示例,以说明您为什么要这样做。)
添加回答
举报