How to pass and call method references in Java

Say I have a class called Server, and I would like to allow others to write for it Plugins. For example Plugin- an interface that enhances Runnableand adds one method: void init(...). The plugin is designed to collect data and send them to the server. However, when it comes time to send data to the server, how to do it? Based on C and C ++, I am looking for thinking along the lines of a function pointer. This is similar to Java, although I have not found any examples outside the standard Java class library.

How to pass a method link to a method initso that it can be saved with Plugin, and then how can I call the method whenever the plugin wants to send data? While say that the desired method of the server: void sendData(Integer data).

For example:

// Inside Server
Plugin p = new PluginImplementation();
p.init(this::sendData);    

// Plugin init
public void init(?? sendMethod) {
    storedSendMethod = sendMethod;
    // ...
}

// Plugin run
public void run() {
    // ...
    storedSendMethod(x) // Sends data to server
    // ...
}
+4
source share
5 answers

Using java.util.function.Function, we can pass the function as an argument to the method, and then use apply()it to apply it to the corresponding arguments. Here is an example:

import java.util.function.Function;

public class FunctionDemo {

    // we will pass a reference to this method
    public static Integer square(Integer x) {
        return x * x;
    }

    // this method accepts the function as an argument and applies it to the input: 5
    public static Integer doSomething(Function<Integer, Integer> func) {
        return func.apply(5);
    }

    public static void main(String[] args) {
        // and here how to use it
        System.out.println(doSomething(FunctionDemo::square)); // prints 25
    }   
}

Additional version with several parameters (passed as an array):

public static Integer sum(Integer[] x) {
    Integer result = 0;
    for(int i = 0; i < x.length; i++)
        result += x[i];
    return result;
}

public static void main(String[] args) {
    Integer[] arr = {1,2,3,4,5};
    System.out.println(doSomething(Play::sum, arr));
}

public static Integer doSomething(Function<Integer[], Integer> func,
                                  Integer[] arr) {        
    return func.apply(arr);
}
+3
source

void sendData(Integer data), , Integer , Consumer<Integer>, accept(Integer), .

, :

public void init(Consumer<Integer> sendMethod) {
    storedSendMethod = sendMethod;
    // ...
}

// Plugin run
 void run() {
    // ...
    storedSendMethod.accept(x) // Sends data to server
   // ...
}

, init, , Java. ,

Plugin p = new PluginImplementation( this::sendData);
+2

java , ,

public interface SendCallback {
    public void doSend(Object toSend);
}

.

public interface Plugin extends Runnable {
    public void init(SendCallback callback);
}

.

public class Server {

    Plugin plugin;

    SendCallback callback = new SendCallback() {
        public void doSend(Object toSend) {
                // logic to send object 'toSend'
        }
    }

    public Server() {
        plugin = new MyPlugin();
        plugin.init(callback);
    }

}

.

public class MyPlugin implements Plugin {
    SendCallback callback = null;
    Object x = null;

    public void init(SendCallback callback) {
        this.callback = callback;
    }
    public void run() {
        x = "Somthing"; // initialize the x object
        callback.doSend(x);
    }
} 

, . doSend.

,

+1

Java 8 has a method reference, however you can just pass the whole object and call its sendData () method. In a โ€œplug-inโ€ situation, using interfaces for each helps the plug-in, and the server has a โ€œlooserโ€ connection.

public interface Server {
    void setData(...);
}

public class MyPlugin implements plugin {

   private Server server;   

   void init(Server s )  {
       this.server = s;
   }

   void run() {
      ...
      this.server.setData(...);
      ...
   }

}
0
source
interface Server{
  ...
  void sendData(String message);
}

The plugin does not need a function reference; you can use the server interface to inform the plugin to find out about this method.

class PluginX implements Plugin{
    ...
    private Server server;
    void init(Server server) {
        this.server = server;
    }

    public void run() {
    // ...
        server.sendData(x) // Sends data to server
    // ...

}}

0
source

All Articles