关于Java 中回调函数的一些理解及与JavaScript的对比
在计算机程序设计中,回调函数,或简称回调,是指通过函数参数传递到其它代码的,某一块可执行代码的引用。这一设计允许了底层代码调用在高层定义的子程序。
上面这段是比较官方的定义,我觉得把”回调函数”称呼为”函数传递”、“方法传递”或“代码传递”,更加容易理解一些。
在JavaScript会中更能诠释这一点,也更好理解一些。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| function caller(callback){ console.log('caller:其他代码逻辑块'); callback("hi callback"); console.log('caller:其他代码逻辑块'); }
function callback(param){ console.log('callback:我被caller调用'); console.log('接收到caller调用我时传递的参数'+param); } caller(callback);
----------
caller(function(param){ console.log('callback:我被caller调用'); console.log('接收到caller调用我时传递的参数'+param); }); </script>
|
输出:
1 2 3 4
| caller:其他代码逻辑块 callback:我被caller调用 接收到caller调用我时传递的参数hi callback caller:其他代码逻辑块
|
在Java中相对就变得麻烦了,由于语言的特性,Java要实现回调函数(代码传递)的话要依赖于接口和匿名实现类
1 2 3 4 5 6 7 8 9 10 11 12
| class Caller{ public void excute(Callback callback){ System.out.println("caller:其他代码逻辑块"); callback.invoke("hi callback"); System.out.println("caller:其他代码逻辑块"); } }
interface Callback{ void invoke(String param); }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| public class CallbackExample { public static void main(String[] args) { Caller caller = new Caller(); caller.excute(new Callback(){ @Override public void invoke(String param) { System.out.println("callback:我被caller调用"); System.out.println("接收到caller调用我时传递的参数"+param); } }); Callback callback = new Callback(){ @Override public void invoke(String param) { System.out.println("callback:我被caller调用"); System.out.println("接收到caller调用我时传递的参数"+param); } }; caller.excute(callback); }); } }
|
输出:
1 2 3 4
| caller:其他代码逻辑块 callback:我被caller调用 接收到caller调用我时传递的参数hi callback caller:其他代码逻辑块
|
我们可以看到,由于Java是静态语言,实现回调函数(代码传递)的话还是很麻烦的,不过在Java8中加入了Lambda表达式,利用它可以使回调函数(代码传递)变得非常简单和优美。
1 2 3 4
| caller.excute((param)->{ System.out.println("callback:我被caller调用"); System.out.println("接收到caller调用我时传递的参数"+param); });
|
输出和上面的一样。
在Java中使用回调函数和代理模式有点相似,都是将重复的代码抽象出来,然后由调用者来回调各自不同的逻辑处理代码。
个人总结:回调函数就是把一段代码传递到调用者的方法内,然后执行这段代码。