Java通过匿名类来实现回调函数
在C语言中,函数名可以当做函数指针传递给形参从而实现回调
void f1() { printf("f1()\n"); }
void f2() { printf("f2()\n"); }
void f3() { printf("f3()\n"); }
void do_func(void(*f)()) { f(); }
int main()
{
do_func(f1);
do_func(f2);
do_func(f3);
}
在C++11中,实现回调还可以通过函数模板和lambda表达式的方式
template <typename Func>
void do_func(Func f) { f(); } int main()
{
do_func([]() { printf("f1()"); });
do_func([]() { printf("f2()"); });
do_func([]() { printf("f3()"); });
}
而假如回调函数的代码实现较为复杂,且具有重用价值,lambda表达式这种一次性的方案就不太适合,在C++11之前,是通过函数对象来实现的。函数对象说白了就是一个类的普通对象,只不过C++可以重载括号运算符,导致调用类的对象的operator()方法时,就像调用函数一样自然。
而分析本质,其实回调函数就是一种函数签名(若干个输入参数、一个输出参数)的规范,java虽不存在函数声明,但是java可以用接口来强制规范。
interface Funcable {
void Func();
}
这样只要实现了该接口的类,都有一个函数签名和void Func()一致的成员函数(嘛,还是不习惯方法(method)这种叫法),于是只需要把实现了该接口的类的对象传入函数中,然后在函数中调用该对象的Func()方法即可
class F1 implements Funcable {
@Override
public void Func() {
System.out.println("f1()");
}
}
public class Test {
public static void do_func(Funcable funcable) {
funcable.Func();
}
public static void main(String[] args) {
do_func(new F1());
}
}
这里节省代码量,就不把类F2、F3给写出来了。并且利用java的匿名类可以节省代码,类似于lambda表达式
do_func(new Funcable() {
@Override
public void Func() {
System.out.println("f2()");
}
});
说到lambda表达式,它是可以捕获外部变量的,在Java这种方式还可以通过匿名内的匿名构造函数来显式捕获外部的变量
String msg = "f3()";
do_func(new Funcable() {
String _msg; {
_msg = msg;
} @Override
public void Func() {
System.out.println(_msg);
}
});
这种做法就很像lambda表达式了,因为匿名类的匿名构造函数是只能以外部变量为构造参数的,相当于lambda表达式的“捕获”,对应C++的lambda表达式写法就是
std::string msg = "f3()";
do_func([&msg]() { std::cout << msg << std::endl; });
java8也有lambda表达式了,因此可以写成这样
do_func(() -> { System.out.println(msg); });
Java通过匿名类来实现回调函数的更多相关文章
- 【java回调】java两个类之间的回调函数传递
背景交代:熟悉用js开发的cordovaAPP:对java一窍不通的我,老师让做一个监测用户拍照事件的功能,无奈没有找到现成的库,无奈自己动手开发java插件~~0基础java GreenHand,祝 ...
- Java JNA (二)—— dll回调函数实现
java调用dll文件需要使用回调函数作为公开函数的参数时,用以下方法实现: 首先,看c++中定义的dll公开函数: typedef void (*ccback)(char *name ,int le ...
- 浅谈Java的匿名类
在实际的项目中看到一个很奇怪的现象,Java可以直接new一个接口,然后在new里面粗暴的加入实现代码.就像下面这样.那么问题来了,new出来的对象没有实际的类作为载体,这不是很奇怪吗? 思考以下代码 ...
- java:使用匿名类直接new接口
java中的匿名类有一个倍儿神奇的用法,见下面代码示例: package contract; public interface ISay { void sayHello(); } 上面是一个简单的接口 ...
- Java之匿名类讲解
参考https://blog.csdn.net/jiaotuwoaini/article/details/51542059 匿名类,正如名字一样在java中没有名字标识的类,当然了编译后还是会安排一个 ...
- Java中Collections类的排序sort函数两种用法
java中的Colletions类主要实现列表List的排序功能.根据函数参数的传递,具体的排序可以分为 : 1. 自然排序(natural ordering). 函数原型:sort(List< ...
- Java中匿名类的两种实现方式(转)
使用匿名内部类课使代码更加简洁.紧凑,模块化程度更高.内部类能够访问外部内的一切成员变量和方法,包括私有的,而实现接口或继承类做不到.然而这个不是我说的重点,我说的很简单,就是匿名内部类的两种实现方式 ...
- Java 在匿名内部函数中为外部函数变量赋值的解决方案
Java匿名内部函数本人不怎么主动使用,但是经常会调用一些API,其中会调用一些接口,而这些接口是需要使用匿名内部类来实现的,于是就遇到了一些问题. 就比如okHttp3 的接口调用 OkHttpCl ...
- java中匿名类的讲解
匿名内部类也就是没有名字的内部类 正因为没有名字,所以匿名内部类只能使用一次,它通常用来简化代码编写 但使用匿名内部类还有个前提条件:必须继承一个父类或实现一个接口 实例1:不使用匿名内部类来实现抽象 ...
随机推荐
- 20162314 Experiment 3 - Sorting and Searching
Experiment report of Besti course:<Program Design & Data Structures> Class: 1623 Student N ...
- 关于函数strtok和strtok_r的使用要点和实现原理(二)【转】
本文转载自:http://astute11.blog.51cto.com/4404646/1334199 (一)中已经介绍了使用strtok函数的一些注意事项,本篇将介绍strtok的一个应用并引出s ...
- ZOJ 2747 Paint the Wall(离散化+暴力)题解
题意:给你一个面,然后涂颜色,问你最后剩多少颜色,每种颜色面积. 思路:第一反应是二维线段树,代码又臭又长,可以做.但是这题暴力+离散化就可以过.可以看到他给的n只有100,也就是说最坏情况下会涂10 ...
- MongoDB排序异常
com.mongodb.MongoQueryException: Query failed with error code 96 and error message 'Executor error d ...
- java.lang.NoSuchMethodError: org.springframework.core.io.ResourceEditor
这种情况一般是jar包版本问题,pom导入的jar包存在一个2.5.6的,删掉即可.
- 由 '' in 'abc' return True 引发的思考----Python 成员测试操作
最近遇到判断字典中是否存在空字符串‘’,这个很好判断,直接用:‘’ in ['a','b','c'],就可以直接判断出来:但是当我对字符串使用 “in” 方法进行判断的时候,发现:‘’ in ‘abc ...
- devdocs
https://devdocs.io/ docker run --rm -d --name devdocs -p 9292:9292 devdocs/devdocs
- 在请求中使用XML Publisher生成文件报错
在页面上使用按钮生成该文件不报错,但是使用请求就报错. 错误内容如下 Error : No corresponding LOB data found :SELECT L.FILE_DATA FILE_ ...
- [Python开发工具] Pycharm之快捷键
[Python开发工具] Pycharm之快捷键 1 全局搜索: Ctrl+Shift+F,不过PyCharm的更强大, 你可以点选左侧某个目录后再按Ctrl+Shift+F, 这样默认会搜索改目录; ...
- 【hive】关于用户留存率的计算
首先用户留存率一般是面向新增用户的概念,是指某一天注册后的几天还是否活跃,是以每天为单位进行计算的.一般收到的需求都是一个时间段内的新增用户的几天留存 (1)找到这个时间段内的新增用户(也可能含有地区 ...