Function Pointers in Java
The Java idiom for function-pointer-like functionality is an an anonymous class implementing an interface, e.g.
Collections.sort(list, new Comparator<MyClass>(){
public int compare(MyClass a, MyClass b)
{
// compare objects
}
});
Update: the above is necessary in Java versions prior to Java 8. Now we have much nicer alternatives, namely lambdas:
list.sort((a, b) -> a.isGreaterThan(b));
and method references:
list.sort(MyClass::isGreaterThan);
What's the nearest substitute for a function pointer in Java?
Anonymous inner class
Say you want to have a function passed in with a String
param that returns an int
.
First you have to define an interface with the function as its only member, if you can't reuse an existing one.
interface StringFunction {
int func(String param);
}
A method that takes the pointer would just accept StringFunction
instance like so:
public void takingMethod(StringFunction sf) {
int i = sf.func("my string");
// do whatever ...
}
And would be called like so:
ref.takingMethod(new StringFunction() {
public int func(String param) {
// body
}
});
EDIT: In Java 8, you could call it with a lambda expression:
ref.takingMethod(param -> bodyExpression);
Function Pointers as Parameters in Java 8
You could accept a Runnable
as argument of doTransaction
and pass it a lambda expression updating the person. Here, we are only using Runnable
as a functional interface that defines a method taking no parameters and returning no value.
public void modifySalary(Person person, float salary) {
doTransaction(() -> person.setSalary(salary));
}
public void doTransaction(Runnable action) {
em.getTransaction().begin();
action.run();
em.getTransaction().commit();
}
If you think the name Runnable is somehow too linked to threads, you could roll your own interface defining a functional method taking no parameters and returning no value. For example, if you want to name it Action
, you could have
@FunctionalInterface
interface Action {
void perform();
}
and then call action.perform()
inside doTransaction
.
Array of function pointers in Java
Java doesn't have a function pointer per se (or "delegate" in C# parlance). This sort of thing tends to be done with anonymous subclasses.
public interface Worker {
void work();
}
class A {
void foo() { System.out.println("A"); }
}
class B {
void bar() { System.out.println("B"); }
}
A a = new A();
B b = new B();
Worker[] workers = new Worker[] {
new Worker() { public void work() { a.foo(); } },
new Worker() { public void work() { b.bar(); } }
};
for (Worker worker : workers) {
worker.work();
}
How are Java 8 method references different from 'real' function pointers?
What is currying?
Currying is the ability to construct a new method reference from an existing method and an argument. e.g.
// this is curried and implied in this method.
BiFunction<String, Integer> m = this::methodTwo;
// create a new curried method.
Function<String> m10 = t -> m.apply(t, 10);
A real example is a consumer
// curry this method so that when called it prints to System.out
Consumer<String> out = System.out::println;
Java 8 method references aren't as powerful as 'true' function pointers.
Java 8 method references are actually a reference to an object which encapsulates a virtual method. This works very well up to a point, but some basic things you might expect you can't do. e.g. equals(), toString(), expression examination won't do what you might expect.
How are method references different from function pointers?
A function pointer is purely a reference to a function. A method reference in Java includes currying information e.g. this a method which has X, Y, Z as know arguments.
does Java 8 support true closures?
Java tends to be minimalist in terms of features, but you can take it as given than no feature in Java is "pure". It has too much backward compatibility issues to deal with that even if there was the will to be pure, it couldn't be.
do we still need to declare a variable final before being able to use it in a lambda?
No, "effectively final" is good enough. i.e. if you could have made it final, it is ok.
Pointer to a function in java
As the comment by @Mark-Rotteveel states, you should define a functional interface with a single method matching the callback. It could look something like this:
// Extend StdCallLibrary if library is __stdcall
public interface YourDLL extends Library {
YourDLL INSTANCE = // insert library loading code here
// Define the callback
// Extend StdCallCallback if library is __stdcall
interface HandleANPREvents extends Callback {
// the function name doesn't matter
void invoke(int event_type, byte param1, int param2);
}
// Define the function using the callback
void set_event_callback(HandleANPREvents callback_fcn);
}
You can then refer to set_event_callback()
in your code.
public static void main(String[] args) {
HandleANPREvents fn = new HandleANPREvents() {
@Override
void invoke(int event_type, byte param1, int param2) {
// implementation here
}
};
YourDLL.INSTANCE.set_event_callback(fn);
}
In Java, how do I create a List of function pointers which take an argument each?
I believe you want to write ImmutableList.of(this::bar, this::foo)
instead of ImmutableList.of((userId) -> this::bar, (userId) -> this::foo)
.
If you do want to use lambdas instead of method references, you should instead write ImmutableList.of((userId) -> this.bar(userId), (userId) -> this.foo(userId))
.
Does JVM know what function pointers are?
Function pointers are a language level construct that Java doesn't have. Since the language nor bytecode supports function pointers, there's no level where they would be relevant (since native code has no concept of them either).
Related Topics
How to Create Executable Java Program
How to Pass a Primitive Data Type by Reference
How to Go About Formatting 1200 to 1.2K in Java
Spring Aop Not Working for Method Call Inside Another Method
How to Access Owl Documents Using Xpath in Java
Initialising Mock Objects - Mockito
Method Chaining + Inheritance Don't Play Well Together
Differencebetween a Local Variable, an Instance Field, an Input Parameter, and a Class Field
Java Garbage Collection Log Messages
How to Create Table Using Ascii in a Console
Open Resource with Relative Path in Java
How to Run Testng from Command Line
How to Serialize an Object into a String
Can't Find a Way to Color the Mandelbrot-Set the Way I'm Aiming For
Spring: How to Inject an Httpservletrequest into a Request-Scoped Bean