I am coming from JavaScript, in which callbacks are pretty easy. I am trying to implement them into JAVA, without success.
I have a Parent class:
import java.net.Socket; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class Server { ExecutorService workers = Executors.newFixedThreadPool(10); private ServerConnections serverConnectionHandler; public Server(int _address) { System.out.println("Starting Server..."); serverConnectionHandler = new ServerConnections(_address); serverConnectionHandler.newConnection = function(Socket _socket) { System.out.println("A function of my child class was called."); }; workers.execute(serverConnectionHandler); System.out.println("Do something else..."); } }
Then I have a child class, that is called from the parent:
import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; import java.util.logging.Level; import java.util.logging.Logger; public class ServerConnections implements Runnable { private int serverPort; private ServerSocket mainSocket; public ServerConnections(int _serverPort) { serverPort = _serverPort; } @Override public void run() { System.out.println("Starting Server Thread..."); try { mainSocket = new ServerSocket(serverPort); while (true) { newConnection(mainSocket.accept()); } } catch (IOException ex) { Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex); } } public void newConnection(Socket _socket) { } }
What is the right way of implementing the
serverConnectionHandler.newConnection = function(Socket _socket) { System.out.println("A function of my child class was called."); };
part, in the Parent class, which is clearly not correct?
A CallBack Function is a function that is passed into another function as an argument and is expected to execute after some kind of event. The purpose of the callback function is to inform a class Sync/Async if some work in another class is done. This is very useful when working with Asynchronous tasks.
There are two types of callbacks, differing in how they control data flow at runtime: blocking callbacks (also known as synchronous callbacks or just callbacks) and deferred callbacks (also known as asynchronous callbacks).
Android Callback Listeners Example:Android maintains the interaction between the end-user and the application using the widely used Listener Design Pattern. All the UI components, like a button, inherit from the View class, which in turns implements the Callback interface from android. graphics.
Define an interface, and implement it in the class that will receive the callback.
Have attention to the multi-threading in your case.
Code example from http://cleancodedevelopment-qualityseal.blogspot.com.br/2012/10/understanding-callbacks-with-java.html
interface CallBack { //declare an interface with the callback methods, //so you can use on more than one class and just //refer to the interface void methodToCallBack(); } class CallBackImpl implements CallBack { //class that implements the method to callback defined //in the interface public void methodToCallBack() { System.out.println("I've been called back"); } } class Caller { public void register(CallBack callback) { callback.methodToCallBack(); } public static void main(String[] args) { Caller caller = new Caller(); CallBack callBack = new CallBackImpl(); //because of the interface, the type is Callback even //thought the new instance is the CallBackImpl class. //This alows to pass different types of classes that have //the implementation of CallBack interface caller.register(callBack); } }
In your case, apart from multi-threading you could do like this:
interface ServerInterface { void newSeverConnection(Socket socket); } public class Server implements ServerInterface { public Server(int _address) { System.out.println("Starting Server..."); serverConnectionHandler = new ServerConnections(_address, this); workers.execute(serverConnectionHandler); System.out.println("Do something else..."); } void newServerConnection(Socket socket) { System.out.println("A function of my child class was called."); } } public class ServerConnections implements Runnable { private ServerInterface serverInterface; public ServerConnections(int _serverPort, ServerInterface _serverInterface) { serverPort = _serverPort; serverInterface = _serverInterface; } @Override public void run() { System.out.println("Starting Server Thread..."); if (serverInterface == null) { System.out.println("Server Thread error: callback null"); } try { mainSocket = new ServerSocket(serverPort); while (true) { serverInterface.newServerConnection(mainSocket.accept()); } } catch (IOException ex) { Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex); } } }
Multi-threading
Remember this does not handle multi-threading, this is another topic and can have various solutions depending on the project.
The observer-pattern
The observer-pattern does nearly this, the major difference is the use of an ArrayList
for adding more than one listener. Where this is not needed, you get better performance with one reference.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With