反射方法类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作为函数参数传递相关推荐

  1. java中函数的调用,java中如何调用函数

    java动态调用函数,Java 中使用动态代码,java函数调用,java中如何调用函数 如何在 Java 中调用 C 函数 宗薇 [期刊名称]<网络新媒体技术> [年(卷),期]2000 ...

  2. 【转载】谈谈我对Java中CallBack的理解

    谈谈我对Java中CallBack的理解 转载自: http://www.cnblogs.com/codingmyworld/archive/2011/07/22/2113514.html CallB ...

  3. Java中的回调函数学习-深入浅出

    Java中的回调函数一般来说分为下面几步: 声明回调函数的统一接口interface A.包括方法callback(); 在调用类caller内将该接口设置为私有成员private A XXX; 在c ...

  4. java中的string函数_java中string.trim()函数的作用实例及源码

    trim()的作用:去掉字符串首尾的空格. public static void main(String arg[]){ String a=" hello world "; Str ...

  5. Java中的split函数

    Java中的 split  函数是用于按指定字符(串)或正则去分割某个字符串,结果以字符串数组形式返回: String str="1234@abc"; String[] a = s ...

  6. Java中获取当前函数名

    Java中获取当前函数名 博客分类: Java JavathreadJDKIDEA  有时候我们需要在程序中获取当前运行的函数名,如何简单的做到这点呢?我们可以用getStackTrace轻松搞定. ...

  7. java中主函数_(基础)java中的主函数

    Java中的主函数 1.由JVM调用:JVM通过类名直接调用主函数(静态方法) 2.主函数的形参是一个字符串数组: String[] args 3.运行主函数时,如果没有向其传递参数,JVM会自动创建 ...

  8. java反转函数_在JAVA中,下列哪个函数可用于字符串的反转?

    在JAVA中,下列哪个函数可用于字符串的反转? 更多相关问题 很多危机是无法准确预测的,必须为危机做好准备,包括().通信计划以及重要关系的建立等. (A) 危 幼儿园科技小制作可分为模型类.动力类. ...

  9. java中string.trim()函数的作用

    java中string.trim()函数的作用 trim的中文含义是修剪,通过其字面意思,我们不难理解这个函数是对字符串进行一定程度的修改删除.那么,具体是如何实现的呢? public static ...

最新文章

  1. python spilt() 方法 ,分隔字符串
  2. uCOS-II任务的挂起和恢复
  3. leetcode733. 图像渲染(bfs)
  4. 【codevs1935】【BZOJ2879】美食节,网络流之动态加点
  5. 安装memcached:error while loading shared libraries: libevent-1.4.so.2
  6. 图片base64编码显示
  7. Junit 单元测试以及断言
  8. android icon换不掉图标文件夹,如何替换android系统中的文件夹图标
  9. 自我介绍html模板王,一分钟自我介绍模板范文15篇
  10. Blazor The specified deps.json \bin\Debug\net5.0\BlazorWebApp.deps.json] does not exist
  11. 每日新闻丨软件业务收入64616亿元;工信部发话广电5G正式启动
  12. mysql capi函数详解_CAPI函数描述(G-N)
  13. 计算机应用基础(专)【9】
  14. GMS2的一些常用函数记录
  15. 卷积神经网络(conv2d参数含义、卷积层、池化层)
  16. Ubuntu 16.04 安装 vivado2018.3
  17. Cholesky和LU矩阵分解
  18. echarts地图插小红旗
  19. C++grammer开篇
  20. 合成孔径雷达成像——算法与实现图【2.11】与【2.12】仿真——不同β值下的kaiser窗,以及3dB宽度和峰值旁瓣比

热门文章

  1. 王者赏金赛源码 可二开 原生开发
  2. 刑事案件不追究刑事责任的情形,办案机关发现后应如何处理?
  3. 图书馆管理系统设计报告
  4. flutter upgrade 报错
  5. 使用ntfs-3g挂载NTFS格式的移动硬盘
  6. 换帅!收购?爱立信能否卷土重来
  7. Gauss型求积公式
  8. Java——JCF简介
  9. hive —— 数据类型
  10. latex error: does not look like a valid PDF document ; xdvipdfmx:fatal: Out of memory - asked for ..