Function Pointers in Java

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



Leave a reply



Submit