Callback Functions in Java

Callback functions in Java

If you mean somthing like .NET anonymous delegate, I think Java's anonymous class can be used as well.

public class Main {

public interface Visitor{
int doJob(int a, int b);
}

public static void main(String[] args) {
Visitor adder = new Visitor(){
public int doJob(int a, int b) {
return a + b;
}
};

Visitor multiplier = new Visitor(){
public int doJob(int a, int b) {
return a*b;
}
};

System.out.println(adder.doJob(10, 20));
System.out.println(multiplier.doJob(10, 20));

}
}

What is a callback method in Java? (Term seems to be used loosely)

A callback is a piece of code that you pass as an argument to some other code so that it executes it. Since Java doesn't yet support function pointers, they are implemented as Command objects. Something like

public class Test {
public static void main(String[] args) throws Exception {
new Test().doWork(new Callback() { // implementing class
@Override
public void call() {
System.out.println("callback called");
}
});
}

public void doWork(Callback callback) {
System.out.println("doing work");
callback.call();
}

public interface Callback {
void call();
}
}

A callback will usually hold reference to some state to actually be useful.

By making the callback implementation have all the dependencies to your code, you gain indirection between your code and the code that is executing the callback.

What is a callback in java

Maybe an example would help.

Your app wants to download a file from some remote computer and then write to to a local disk. The remote computer is the other side of a dial-up modem and a satellite link. The latency and transfer time will be huge and you have other things to do. So, you have a function/method that will write a buffer to disk. You pass a pointer to this method to your network API, together with the remote URI and other stuff. This network call returns 'immediately' and you can do your other stuff. 30 seconds later, the first buffer from the remote computer arrives at the network layer. The network layer then calls the function that you passed during the setup and so the buffer gets written to disk - the network layer has 'called back'. Note that, in this example, the callback would happen on a network layer thread than the originating thread, but that does not matter - the buffer still gets written to the disk.

How do I perform a JAVA callback between classes?

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.

Callback Method Android

Chris, Imagine that you have a function:

fun test() {
...
}

Then you decided to add some magic to it. For instance, add 'block' that could be done after function test finished its job. So, here we need to put some extra into code:

interface CallbackInterface {
fun doJob()
}

and your function become:

fun test(block: CallbackInterface) {
...
block.doJob()
}

so then you can call your test function like this (or pass CallbackInterface into test function):

test(object: CallbackInterface {
override fun doJob() {
...
}
})

In general, the point is to pass the interface as a parameter in function and call it whenever you want and do on another end do whatever you want with the results.

or in Kotlin you can do like this:

fun test(block: ()-> Unit) {
...
block.invoke() // or just block()
}

and use it:

test {
...
}

Java simple callback

You can define an interface for the callback.

interface Callback{
void call();
}

Then, let class A implement it.

class A implements Callback{
private B b;

public A(){
b = new B();
b.registerCallback(this);
}

// Implementation of the callback interface
public void call(){

}
}

Then, let class B to handle the callback.

public class B
{
private Callback callbackoNotify;

public class registerCallback(Callback callback)
{
callbackoNotify = callback;
}

public void notify()
{
callbackNotify.call();
}
}

But in the above scenario, callbackNotify can be null. Therefore, it is better if you can pass that callback in the constructor to B.

Hope you got the idea.

Java callback functions as parameter

create a static class:

private static class MyCallback implements MyCallbackInterface  {

@Override
public void onDownloadFinished(String result) {
//do something ...
}
}

and then call using

DoAsyncRequest("http://toto.com", new MyCallBack());

You can't do

private void MyCallBack(string result){
//do something
}

as your callback is expected to be one of the object type and not method. Also it's not inline method, it's anonymous class that we call and which is much similar to class defined above except it doesn't have any name but you are implementing the method by overriding.

what do you mean by callbacks?

LifeCycle

In the context of Spring beans (which I believe is the context of what you are reading - hard to tell with the little info you've provided), beans go through different lifecycle phases (like creation and destruction). Here are the lifecycle phases of the Spring bean you can hook into:

Sample Image

Callback

@R.T.'s wikipedia link to what a callback is, is a good starting point to understanding callbacks. In Java, the concept of callback is implemented differently.

In object-oriented programming languages without function-valued arguments, such as in Java before its 1.7 version, callbacks can be simulated by passing an instance of an abstract class or interface, of which the receiver will call one or more methods, while the calling end provides a concrete implementation.

A good example is given by @SotiriosDelamanolis in this answer, which I'll post here just for context.

/**
* @author @SotiriosDelamanolis
* see https://stackoverflow.com/a/19405498/2587435
*/
public class Test {
public static void main(String[] args) throws Exception {
new Test().doWork(new Callback() { // implementing class
@Override
public void call() {
System.out.println("callback called");
}
});
}

public void doWork(Callback callback) {
System.out.println("doing work");
callback.call();
}

public interface Callback {
void call();
}
}

LifeCycle Callback

By looking at the image above, you can see that Spring allows you to hook into the bean lifecyle with some interfaces and annotations. For example

Hooking into the bean creation part of the lifecycle, you can implements InitializingBean, which has a callback method afterPropertiesSet(). When you implements this interface, Spring pick up on it, and calls the afterPropertiesSet().

For example

public class SomeBean implements InitializingBean {
@Override
public void afterPropertiesSet() { // this is the callback method
// for the bean creation phase of the
// spring bean lifecycle
// do something after the properties are set during bean creation
}
}

Alternatively, you can use the @PostConstruct method for a non-InitializingBean implemented method, or using the init-method in xml config.

The diagram shows other lifecycle phases you can hook into and provide "callback" method for. The lifecycle phases are underlined at the top in the diagram

You can see more at Spring reference - Lifecycle Callbacks



Related Topics



Leave a reply



Submit