在Java 8中,是否可以连续调用2个引用方法?
customer::new::getName
可以连接2种方法参考形式:
a::b::c
答案 0 :(得分:3)
让我们分解Customer::new::getName
表达式;
T1 customer = Customer::new;
T2 name = customer::getName;
根据JLS描述的方法参考表达式,因此T1
和T2
必须为FunctionalInterface。
如果T是函数接口类型(第9.8节)且表达式与地面目标类型的函数类型一致,则方法引用表达式在赋值上下文,调用上下文或具有目标类型T的转换上下文中是兼容的源自T。
当Supplier<Customer>
与T1
一起使用时,编译器会报告错误:无法解析在供应商上定义的方法getName 。但您可以定义自己的FunctionalInterface,例如:CustomerSupplier
。
interface CustomerSupplier {
Customer get();
default String getName() {
return get().getName();
}
}
然后您可以将Customer::new
推荐给CustomerSupplier
:
CustomerSupplier customer = Customer::new;
Supplier<String> name = customer::getName;
实际上,您可以进一步将两个表达式内联在一起,但每个方法引用表达式必须是FunctionalInterface,因此您必须将Customer::new
强制转换为CustomerSupplier
。
Supplier<String> customerName = ((CustomerSupplier) Customer::new)::getName;
然而,最简单的就是直接访问@Holger提供的内容。
Supplier<String> customerName = () -> new Customer().getName();
由于Supplier
没有组合FunctionInterface的方法,但您可以像这样链接方法引用表达式:
interface Reference<T> extends Supplier<T> {
static <T> Reference<T> of(Supplier<T> reference) {
return reference::get;
}
default <R> Reference<R> of(Function<T, R> after) {
return () -> after.apply(get());
}
}
//NOTE:Reference is derived from Supplier, so it is compatible with Supplier.
Supplier<String> customerName = Reference.of(Customer::new).of(Customer::getName);
但是,您可以引入一种方法来避免引入用于组合@Holger提供的函数接口的类型。
private <T, R> Supplier<R> map(Supplier<T> target, Function<T, R> mapper) {
return () -> mapper.apply(target.get());
}
Supplier<String> customerName = map(Customer::new, Customer::getName);
答案 1 :(得分:1)
不,您无法链接两个方法引用。
基本上,方法引用是一种语法糖,它允许您将现有方法的定义传递给Lambda表达式(实现单abstract
方法)。
答案 2 :(得分:1)
在Java 8中,是否可以连续调用2个引用方法?
不,在使用方法引用时链接方法是不可能的,因为方法引用本质上是执行 ONE 方法的lambda表达式的简写语法。因此,一旦开始链接方法,它将不再是方法引用的有效语法。
<强>语法强>
Object::methodName