Java callback four written (reflection, direct call, interface calls, Lambda expressions)

1 Introduction

In computer programming, the callback function , referred to as callback (the Callback), it refers to other references passed by a function code parameter, a piece of executable code. This design allows the underlying code to call the subroutine level definition.

These are the Wikipedia definition of "callback function". For callback, different languages ​​have different callbacks, for example:

  • C, C ++ allows the function pointer passed as a parameter;
  • JavaScript, Python allows function name as a parameter.

This article will introduce four kinds written in Java callback:

  • reflection;
  • Direct call;
  • Interface calls;
  • Lambda expressions.

Before starting, first introduced in the context of the code examples herein, the main function, we send an asynchronous request, and in response to the callback function designation process, the main function then do other things, and when the response arrives, the callback function is executed.

2. Reflector

Java's reflection mechanism allows us to obtain information about classes, including the class methods. We will go to get the callback function Method type, then the request is passed to the function. Examples are as follows:

Request class send method has two parameters clazz, method, and were of type Class Method type, where the method parameter is a callback function to be passed, and in order to invoke the method is reflected by a call, but also an example, it will be class object class where the callback function passed in as a parameter, an object constructed by newInstance the reflection pass invoke call.

public class Request{
    public void send(Class clazz, Method method) throws Exception {
        // 模拟等待响应
        Thread.sleep(3000);
        System.out.println("[Request]:收到响应");
        method.invoke(clazz.newInstance());
    }
}
复制代码

CallBack class is very simple, and only a processResponse method, as for the callback function, treatment response.

public class CallBack {
    public void processResponse() {
        System.out.println("[CallBack]:处理响应");
    }
}
复制代码

We are the main method, opened a new thread to send the request, and the need CallBack.class and processResponse way to pass inside.

public class Main {
    public static void main(String[] args) throws Exception {
        Request request = new Request();
        System.out.println("[Main]:我开个线程去异步发请求");
        new Thread(() -> {
            try {
                request.send(CallBack.class, CallBack.class.getMethod("processResponse"));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }).start();
        System.out.println("[Main]:请求发完了,我去干点别的");
        Thread.sleep(100000);
    }
}
/** Output:
[Main]:我开个线程去异步发请求
[Main]:请求发完了,我去干点别的
[Request]:收到响应
[CallBack]:处理响应
*/
复制代码

The wording needs to pass parameters is very complicated, it is not recommended. Here are the simple direct call writing.

3. Direct call

Let's rewrite the parameters of the send method instead a CallBack type parameter. as follows:

In the send method, we do not use reflection to invoke methods to direct through an object.

public class Request{
    public void send(CallBack callBack) throws Exception {
        // 模拟等待响应
        Thread.sleep(3000);
        System.out.println("[Request]:收到响应");
        callBack.processResponse();
    }
}
复制代码

the main function, we have a new CallBack object is passed as a parameter to the send method.

public class Main {
    public static void main(String[] args) throws Exception {
        Request request = new Request();
        System.out.println("[Main]:我开个线程去异步发请求");
        CallBack callBack = new CallBack();
        new Thread(() -> {
            try {
                request.send(callBack);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }).start();
        System.out.println("[Main]:请求发完了,我去干点别的");
        Thread.sleep(100000);
    }
}
复制代码

This implementation is very simple, but the problem is not in line with the principle of modified closed. That is when we want to change a "processing response" method, will have to modify processRequest () method CallBack class. If the CallBack class changed the interface, we can replace only the realization of a CallBack. The following wording interface calls look.

4. interface calls

First class CallBack changed interface.

public interface CallBack {
    public void processResponse();
}
复制代码

Then add a class that implements CallBackImpl CallBack interface.

public class CallBackImpl implements CallBack {
    @Override
    public void processResponse() {
        System.out.println("[CallBack]:处理响应");
    }
}
复制代码

Request class unchanged. Main class main method instantiates a CallBackImpl, then pass through into the CallBack interface.

public class Main {
    public static void main(String[] args) throws Exception {
        Request request = new Request();
        System.out.println("[Main]:我开个线程去异步发请求");
        CallBack callBack = new CallBackImpl();
        new Thread(() -> {
            try {
                request.send(callBack);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }).start();
        System.out.println("[Main]:请求发完了,我去干点别的");
        Thread.sleep(100000);
    }
}
复制代码

5. Lambda Expressions

These methods are already introduced almost, and finally we'll introduce a more concise wording, by using Lamda expression, you will not have to add a class that implements CallBack interface. See below the main method rewritten:

public class Main {
    public static void main(String[] args) throws Exception {
        Request request = new Request();
        System.out.println("[Main]:我开个线程去异步发请求");
        new Thread(() -> {
            try {
                request.send(()-> System.out.println("[CallBack]:处理响应"));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }).start();
        System.out.println("[Main]:请求发完了,我去干点别的");
        Thread.sleep(100000);
    }
}
复制代码

We do not take up the new implementation class, do not take instantiated, only need to pass Lambda expressions can be completed callback.

6. Summary

To give you a better understanding of the callback, the paper describes a total of four kinds of writing, in addition to the reflection is not recommended, the other three are self-created according to their needs.

I like the article junior partner, you can sweep under the code number of public concern me: "Pinch grass child"

Guess you like

Origin juejin.im/post/5e4948c7e51d4526c70fa2ec