Reputation: 469
someone can help me understand below code from Java 8 Functional Interface As per my understanding accept() takes as input and process it but does not return any value then in case of andThen() how it works
accept() method takes as input the type T and returns no value.
default Consumer<T> andThen(Consumer<? super T> after) {
Objects.requireNonNull(after);
return (T t) -> { accept(t); after.accept(t); };
}
Upvotes: 5
Views: 4206
Reputation: 2955
I think I understand your concern. You wonder why could you call andThen()
after accept()
if accept()
returns void.
The thing is, that you first define a Consumer
object, and on that instance you call andThen()
method. For example:
Consumer<String> consumer = s -> System.out.println(s);
consumer.andThen(s -> System.out.println(s.toUpperCase()));
Upvotes: 0
Reputation: 31878
In order to understand what is getting return
ed from that API, you can try visualizing the implementation as :
default Consumer<T> andThen(Consumer<? super T> after) {
Objects.requireNonNull(after);
return new Consumer<T>() { // return the complete Consumer implementation
@Override
public void accept(T t) {
Consumer.this.accept(t); // accept current consumer
after.accept(t); // and then accept the 'after' one.
}
};
}
and now relate that
(T t) -> { accept(t); after.accept(t); }
is a Consumer
returned which ensures that the current one is accept
ed first and then the one mentioned as after
.
Upvotes: 3
Reputation: 45806
A functional interface must have only one abstract method. However, it can have as many static and default methods as you'd like. The methods of Consumer
are:
accept(T)
Consumer
. It accepts a single generic argument of type T
and returns nothing (i.e. void
). This is the method that's implemented by a lambda expression or method reference.andThen(Consumer)
Consumer
and returns another Consumer
. Since it's a default method, the single abstract method of Consumer
remains accept(T)
.The above explains why Consumer
can have a method that returns something other than void
. Now, when it comes to the implementation of andThen
, it's important to realize there are actually three Consumer
s involved:
andThen
was invoked.after
.If you format the code so not everything is on the same line it may be easier to follow:
default Consumer<T> andThen(Consumer<? super T> after) {
Objects.requireNonNull(after);
// Returns Consumer instance #3. The lambda is the implementation
// of the 'accept' method.
return (T t) -> {
accept(t); // Invokes 'accept' on Consumer instance #1.
after.accept(t); // Invokes 'accept' on Consumer instance #2.
}
}
Upvotes: 3