Java中callback作为函数参数传递
反射方法类Method
需要callback函数为变量时,java通常用反射(java.lang.reflect)的相关方法。
import java.lang.reflect.Method;
利用Method类和invoke方法实现传递callback
例如
以TestAClass.AddProduce(int a, int b)是需要回调的函数,为了体现函数作为参数可变的优势,这里写2个回调函数:
public class TestAClass {ArrayList<Integer> list = new ArrayList<>();public void AddProduct(int a, int b) {list.add(a * b);}public void AddSum(int a, int b) {list.add(a + b);}
}
TestBClass.testCall()是被调函数:
public class TestBClass {public void testCall(Method func) throws Exception {TestAClass aobj = new TestAClass();for (int i = 0; i < 10; i++)func.invoke(aobj, i, i + 1);}
}
执行invoke时第一个参数需要执行的对象。在上面代码中是新建了一个AClass对象,这样的话会导致对象的类还是在方法中被严格限制。
虽然这里可能可以用func.getDeclaringClass()
来获取目标类型,但是我们仍然有可能希望限制执行回调函数的对象。
因此当我们希望执行回调的对象也是特定变量时,就需要改为:
public class TestBClass {public void testCall(object obj, Method func) throws Exception {for (int i = 0; i < 10; i++)func.invoke(obj, i, i + 1);}
}
调用这个函数时:
TestAClass tcb = new TestAClass();TestBClass tc = new TestBClass();Method callback = new Method(tcb.getClass().getMethod("AddProduct", int.class, int.class));tc.testCall(tcb, callback);for (int i : tcb.list) {System.out.println(i);}tcb.list.clear();System.out.println("-------");callback = new Method(tcb.getClass().getMethod("AddSum", int.class, int.class));tc.testCall(tcb, callback);for (int i : tcb.list) {System.out.println(i);}
至此就可以完成传递回调函数作为变量。
封装CallBack类
每当我们需要把一个函数的回调函数改为变参时,我们就需要同时在调用函数的参数和invoke上加上obj、method这2个参数,当频繁添加回调时感觉很麻烦。因此考虑重新封装一个CallBack类,简化回调的参数。
如下:
public class CallBack {Object ownobj;Method execute;public CallBack(Object o, Method method) {ownobj = o;execute = method;}public Object invoke(Object... args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException{return execute.invoke(ownobj, args);}
}
回调函数无变化:
public class TestAClass {ArrayList<Integer> list = new ArrayList<>();public void AddProduct(int a, int b) {list.add(a * b);}public void AddSum(int a, int b) {list.add(a + b);}
}
调用函数简化为:
public class TestBClass {public void testCall(CallBack func) throws Exception {for (int i = 0; i < 10; i++)func.invoke(i, i + 1);}
}
调用改为:
TestAClass tcb = new TestAClass();TestBClass tc = new TestBClass();CallBack callback = new CallBack(tcb, tcb.getClass().getMethod("AddProduct", int.class, int.class));tc.testCall(callback);for (int i : tcb.list) {System.out.println(i);}tcb.list.clear();System.out.println("-------");callback = new CallBack(tcb, tcb.getClass().getMethod("AddSum", int.class, int.class));tc.testCall(callback);for (int i : tcb.list) {System.out.println(i);}
执行结果:
0
2
6
12
20
30
42
56
72
90
-------
1
3
5
7
9
11
13
15
17
19
后记
目前发现invoke 不支持以String[]作为多态参数。可以转化为ArrayList传递
Java中callback作为函数参数传递相关推荐
- java中函数的调用,java中如何调用函数
java动态调用函数,Java 中使用动态代码,java函数调用,java中如何调用函数 如何在 Java 中调用 C 函数 宗薇 [期刊名称]<网络新媒体技术> [年(卷),期]2000 ...
- 【转载】谈谈我对Java中CallBack的理解
谈谈我对Java中CallBack的理解 转载自: http://www.cnblogs.com/codingmyworld/archive/2011/07/22/2113514.html CallB ...
- Java中的回调函数学习-深入浅出
Java中的回调函数一般来说分为下面几步: 声明回调函数的统一接口interface A.包括方法callback(); 在调用类caller内将该接口设置为私有成员private A XXX; 在c ...
- java中的string函数_java中string.trim()函数的作用实例及源码
trim()的作用:去掉字符串首尾的空格. public static void main(String arg[]){ String a=" hello world "; Str ...
- Java中的split函数
Java中的 split 函数是用于按指定字符(串)或正则去分割某个字符串,结果以字符串数组形式返回: String str="1234@abc"; String[] a = s ...
- Java中获取当前函数名
Java中获取当前函数名 博客分类: Java JavathreadJDKIDEA 有时候我们需要在程序中获取当前运行的函数名,如何简单的做到这点呢?我们可以用getStackTrace轻松搞定. ...
- java中主函数_(基础)java中的主函数
Java中的主函数 1.由JVM调用:JVM通过类名直接调用主函数(静态方法) 2.主函数的形参是一个字符串数组: String[] args 3.运行主函数时,如果没有向其传递参数,JVM会自动创建 ...
- java反转函数_在JAVA中,下列哪个函数可用于字符串的反转?
在JAVA中,下列哪个函数可用于字符串的反转? 更多相关问题 很多危机是无法准确预测的,必须为危机做好准备,包括().通信计划以及重要关系的建立等. (A) 危 幼儿园科技小制作可分为模型类.动力类. ...
- java中string.trim()函数的作用
java中string.trim()函数的作用 trim的中文含义是修剪,通过其字面意思,我们不难理解这个函数是对字符串进行一定程度的修改删除.那么,具体是如何实现的呢? public static ...
最新文章
- python spilt() 方法 ,分隔字符串
- uCOS-II任务的挂起和恢复
- leetcode733. 图像渲染(bfs)
- 【codevs1935】【BZOJ2879】美食节,网络流之动态加点
- 安装memcached:error while loading shared libraries: libevent-1.4.so.2
- 图片base64编码显示
- Junit 单元测试以及断言
- android icon换不掉图标文件夹,如何替换android系统中的文件夹图标
- 自我介绍html模板王,一分钟自我介绍模板范文15篇
- Blazor The specified deps.json \bin\Debug\net5.0\BlazorWebApp.deps.json] does not exist
- 每日新闻丨软件业务收入64616亿元;工信部发话广电5G正式启动
- mysql capi函数详解_CAPI函数描述(G-N)
- 计算机应用基础(专)【9】
- GMS2的一些常用函数记录
- 卷积神经网络(conv2d参数含义、卷积层、池化层)
- Ubuntu 16.04 安装 vivado2018.3
- Cholesky和LU矩阵分解
- echarts地图插小红旗
- C++grammer开篇
- 合成孔径雷达成像——算法与实现图【2.11】与【2.12】仿真——不同β值下的kaiser窗,以及3dB宽度和峰值旁瓣比