在Java 8中是否可以连续调用2个引用方法?
customer::new::getName
可以串联2个形式的方法引用:
a::b::c
最佳答案
如何内联两个方法引用表达式?
让我们分解Customer::new::getName
表达;
T1 customer = Customer::new;
T2 name = customer::getName;
根据JLS描述了方法引用表达式,所以 T1
和T2
必须是FunctionalInterface .
A method reference expression is compatible in an assignment context, invocation context, or casting context with a target type T if T is a functional interface type (§9.8) and the expression is congruent with the function type of the ground target type derived from T.
当您使用Supplier<Customer>
时与 T1
然后编译器报告错误:无法解析供应商上定义的方法 getName。但您可以定义自己的功能接口(interface),例如: 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 提供的用于组合函数接口(interface)的类型。 .
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);
关于Java 8 方法引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43195051/