Reputation: 2777
I've read today about the Java 8 release. But I don't understand fully the concept of reference methods in Java 8. Does this mean that Java now has the support of functions as first class objects? I have seen, how to construct a reference to function. But it seems to me, that the Converter object they provide has quite limited functionality. Is it now possible in Java:
Upvotes: 12
Views: 14460
Reputation: 21836
It is possible. How do you do it?
First construct a "Functional Interface" (or use one of the provided ones). A functional interface is an interface with a single method. java.lang.Runnable is an example.
Second, write a method that takes a functional interface as a parameter.
public void doAThing(Runnable r) {
r.run();
}
Third, write a method with the correct signature.
public class MyClass {
public void runAThing() {
System.out.println("I executed!");
}
}
Fourth, call the function passing in a method reference.
MyClass mc = new MyClass();
doAThing(mc::runAThing);
You'll note that none of the classes you've wrote ever explicitly implements Runnable
. This is handled for you by the compiler.
You can do something similar using a lamdba expression:
doAThing(() -> System.out.println("I executed as a lamdba expression!"));
To return the function as a value from another function, just return an instance of Runnable
.
Upvotes: 8
Reputation: 200168
The most important aspects of first-class functions have been blended into the existing Java type system. No true function type has been introduced; any single-method interface is its own "function type". So, as for your first two questions, you can freely pass around instances of such functional interfaces.
There are many subtle changes to the semantics, which allow one to use lambda syntax/method references to implement any such interface. You can even use higher-order functions such as compose
, which returns a generic Function
type, and pass it to a method which expects a compatible functional interface type.
you cannot change the value of the variable you reference in a closure
This is not a limitation specific to Java. In fact, most FP languages don't support mutable variables of any kind. Note that there is no requirement to use the final
keyword on the variable; the concept of effectively final takes care of that.
Upvotes: 11
Reputation: 47290
No, not first class functions. Lambda expression are wrapped in a interface, and some syntatic sugar applied for brevity.
But you can;t create a function on its own and pass it around different methods, whether thats a key point or not is a different question.
Upvotes: 3
Reputation: 69269
Methods are not first class objecs in Java, apart from the already existing usage in reflection, to answer your questions:
Yes, you can pass it on, but it needs to satisfy the signature.
void method()
you use a Runnable
, like this:Runnable method = this::method
if it is in the same class, and then run the actual method with method.run()
.double method()
you need to use a DoubleSupplier
, like this:
DoubleSupplier method = this::method
, and then use it as double d = method.get()
.Yes it is possible, but only specific signatures as shown in Point 1.
Lambdas behave exactly as anonymous inner classes, which are closures by itself, Java has had support for closures since they introduced anonymous inner classes. The only thing that is added now is that the syntax is much prettier.
Upvotes: 4