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:
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
Drawing in Jlayeredpane Over Exising JPAnels
Format File Size as Mb, Gb, etc
Drawing a Simple Line Graph in Java
Sending Mail Attachment Using Java
Validate Jaxbelement in JPA/Jax-Rs Web Service
Bug with Varargs and Overloading
Tool for Analyzing Large Java Heap Dumps
Technique or Utility to Minimize Java "Warm-Up" Time
Httpurlconnection Timeout Settings
How to Display a Svg Byte Array as an Image in a Jasperreport
Get Maven Artifact Version at Runtime
Differencebetween Closeablehttpclient and Httpclient in Apache Httpclient API
Getting Java.Lang.Classnotfoundexception: Org.Apache.Commons.Logging.Logfactory Exception
Why Can't a Generic Type Parameter Have a Lower Bound in Java
Using a Jfilechooser with Swing Gui Classes and Listeners
Cannot Resolve Constructor Firefoxdriver(Org.Openqa.Selenium.Firefox.Firefoxprofile)
How to Programmatically Set the Sslcontext of a Jax-Ws Client