java addcallback函数_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 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 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传递

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java 实现 gRPC server Future.addCallBack 方式异步调用的步骤如下: 1. 定义 proto 文件,包括服务名和方法名,以及请求和响应的数据类型。 2. 根据 proto 文件生成 java 代码。 3. 编写实现服务方法的类。 4. 在服务端启动时注册服务方法。 5. 在客户端调用服务方法时,使用 Future 实例进行异步调用,并添加回调函数。 以下是一个简单的示例代码: ```protobuf syntax = "proto3"; package myservice; service MyService { rpc MyMethod(MyRequest) returns (MyResponse); } message MyRequest { string message = 1; } message MyResponse { string message = 1; } ``` 根据这个 proto 文件生成 java 代码: ``` $ protoc --java_out=. myservice.proto ``` 然后编写实现服务方法的类: ```java package mypackage; import mypackage.MyServiceGrpc.MyServiceImplBase; import mypackage.MyServiceOuterClass.MyRequest; import mypackage.MyServiceOuterClass.MyResponse; import io.grpc.stub.StreamObserver; public class MyServiceHandler extends MyServiceImplBase { @Override public void myMethod(MyRequest request, StreamObserver<MyResponse> responseObserver) { // 处理请求 String message = request.getMessage(); String responseMessage = "Hello, " + message; // 构造响应 MyResponse response = MyResponse.newBuilder() .setMessage(responseMessage) .build(); // 发送响应 responseObserver.onNext(response); responseObserver.onCompleted(); } } ``` 在服务端启动时注册服务方法: ```java package mypackage; import io.grpc.Server; import io.grpc.ServerBuilder; import java.io.IOException; public class MyServer { public static void main(String[] args) throws IOException, InterruptedException { int port = 50051; Server server = ServerBuilder.forPort(port) .addService(new MyServiceHandler()) .build(); System.out.println("Starting server..."); server.start(); System.out.println("Server started!"); server.awaitTermination(); } } ``` 在客户端调用服务方法时,使用 Future 实例进行异步调用,并添加回调函数: ```java package mypackage; import mypackage.MyServiceGrpc.MyServiceFutureStub; import mypackage.MyServiceOuterClass.MyRequest; import mypackage.MyServiceOuterClass.MyResponse; import io.grpc.ManagedChannel; import io.grpc.ManagedChannelBuilder; import io.grpc.stub.StreamObserver; import java.util.concurrent.CompletableFuture; public class MyClient { public static void main(String[] args) throws Exception { String message = "World"; ManagedChannel channel = ManagedChannelBuilder.forAddress("localhost", 50051) .usePlaintext() .build(); MyServiceFutureStub stub = MyServiceGrpc.newFutureStub(channel); CompletableFuture<MyResponse> future = stub.myMethod(MyRequest.newBuilder().setMessage(message).build()); future.addCallback(new CompletableFuture.Callback<MyResponse>() { @Override public void onSuccess(MyResponse response) { // 处理响应 String message = response.getMessage(); System.out.println("Received response: " + message); } @Override public void onFailure(Throwable t) { // 处理错误 System.err.println("Error: " + t.getMessage()); } }); // 阻塞等待结果 future.get(); } } ``` 以上就是 gRPC server Future.addCallBack 方式异步调用的 Java 实现步骤,希望能对你有所帮助。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值