Function Pointers in Java
Java does not provide function pointers in the same way C/C++ does.
Instead of passing a function pointer f
, you create an object with an instance method f
and pass the object instead. With lambdas and method refernecs the syntactical overhead for doing this is close to zero.
Using a method reference
class Example {
// Method that takes a "method" as argument
static void exampleMethod(Runnable toRun) {
toRun.run();
}
// Method to pass
static void sayHello() {
System.out.println("Hello");
}
public static void main(String[] args) {
exampleMethod(Example::sayHello); // prints "Hello"
}
}
Using a lambda
You may also invoke the exampleMethod
above as follows:
exampleMethod(() -> System.out.println("Hello"));
For similar examples with different method signatures, see the Lambda Cheat Sheet.
Using ordinary objects
The above examples requires Java 8. Here's how to do it in Java 7:
exampleMethod(new Runnable() {
@Override
public void run() {
System.out.println("Hello");
}
});
Using reflection
You can use reflection to pass actual Method
objects and Method.invoke
to invoke the method. This is not recommended and often seen as a hack / last resort.
import java.lang.reflect.Method;
class Example {
static void exampleMethod(Method toInvoke) throws Exception {
// null as callee for static methods
toInvoke.invoke(null);
}
public static void sayHello() {
System.out.println("Hello");
}
public static void main(String[] args) throws Exception {
// prints "Hello"
exampleMethod(Example.class.getMethod("sayHello"));
}
}
A real world use case
Let's take a look at a more realistic use case.
Example: Storing "methods" in a hash map
import java.util.*;
class Example {
public static void main(String[] args) {
Map<Character, Runnable> commands = new HashMap<>();
// Populate commands map
commands.put('h', () -> System.out.println("Type h or q"));
commands.put('q', () -> System.exit(0));
while (true) {
// Print menu
System.out.println("Menu");
System.out.println("h) Help");
System.out.println("q) Quit");
// User input
char key = new Scanner(System.in).nextLine().charAt(0);
// Run selected command
if (commands.containsKey(key))
commands.get(key).run();
}
}
}
Awesome guide, many thanks
by Felipe Amorim |