2

In Java 8 is it possible to call 2 reference methods in a row?

customer::new::getName

Can be concatenated 2 methods reference of the form:

a::b::c
ZhekaKozlov
40.1k20 gold badges143 silver badges166 bronze badges
asked Apr 3, 2017 at 22:01
3

3 Answers 3

3

How to inline two method reference expression ?

Let's decomposing Customer::new::getName expression;

T1 customer = Customer::new;
T2 name = customer::getName; 

according JLS described Method Reference Expression,so T1 and T2 must are 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.

when you use Supplier<Customer> with T1 then the compiler reports error:can't resolve method getName defined on Supplier. but you can define your own FunctionalInterface, e.g: CustomerSupplier.

interface CustomerSupplier {
 Customer get();
 default String getName() {
 return get().getName();
 }
}

then you can refer Customer::new to CustomerSupplier:

CustomerSupplier customer = Customer::new;
Supplier<String> name = customer::getName;

Indeed, you can inline two expression together in further, but each method reference expression must be a FunctionalInterface, so you must cast Customer::new to CustomerSupplier.

Supplier<String> customerName = ((CustomerSupplier) Customer::new)::getName;

However, the simplest one is access directly that provided by @Holger.

Supplier<String> customerName = () -> new Customer().getName();

How to chain two method reference expression ?

Due to Supplier has no methods for composing FunctionInterface, but you can chain the method reference expression like this:

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);

However, you can introduce a method to avoid introduce a type for composing Function Interfaces that provided by @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);
answered Apr 4, 2017 at 8:26
Sign up to request clarification or add additional context in comments.

Comments

1

In Java 8 is it possible to call 2 reference methods in a row?

No, it's not possible to chain methods when using method references because a method reference is essentially a shorthand syntax for a lambda expression that executes just ONE method. Hence, once you start chaining methods it would no longer be valid syntax for a method reference.

syntax

Object::methodName
answered Apr 3, 2017 at 22:05

Comments

1

No, you can't chain two method references.

Basically, a method reference is a syntactic sugar which will allow you to pass the definition of an existing method to a Lambda expression (which implements single abstract method).

answered Apr 3, 2017 at 22:05

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.