简体   繁体   English

需要有关Java中的回调和匿名类的帮助

[英]Need help with callbacks and anonymous classes in Java

I am using some third party library to connect to a server via async protocol and get response back. 我正在使用一些第三方库通过异步协议连接到服务器并获得响应。 For example method to get userid by username looks like this: 例如,通过用户名获取userid的方法如下所示:

public int getUserid(String username) {
        int userid = 0;

    connection.call("getUserid", new Responder() {
        public void onResult(final int result) {
            System.out.println("userid: " + result);
            //how to assign received value to userid and return it?
        }
    }, username);

    //wait for response
    while (userid == 0) {
            try{
                Thread.sleep(100);
            } catch (Exception e) {}
        }


        return userid;
}

The problem is I can't assign returned "result" from server response to "userid" variable from the method (in order to return it after). 问题是我无法从服务器响应中将返回的“结果”分配给方法中的“userid”变量(以便在之后返回)。 How to solve this? 怎么解决这个? I probably can assign it to some class variable rather than method variable but I want to keep it within method scope so I don't have to deal with concurrency issues. 我可能可以将它分配给某个类变量而不是方法变量,但我想将它保留在方法范围内,这样我就不必处理并发问题了。

Thanks. 谢谢。

If I understand your question correctly, you're asking how you can write a variable from inside an anonymous class. 如果我正确理解你的问题,你就会问如何从匿名类中编写变量。

Anonymous classes can only access final variables, and can't directly "write" them. 匿名类只能访问最终变量,不能直接“写”它们。

A straightforward solution that is "good enough" is to create sort of a ValueBox class with a single value field and a getter and setter. 一个“足够好”的直接解决方案是使用单个值字段和getter和setter创建ValueBox类。 You can then instantiate a new one in the function as a final variable, and have your anonymous class access it. 然后,您可以在函数中将新的实例化为最终变量,并让您的匿名类访问它。 The anonymous class will use its getter and setter to write/read. 匿名类将使用其getter和setter来编写/读取。

The fact that the variable is final just means that you can't aim the reference anywhere else, but you can still change the contents of the referred object from either function. 变量是final的这一事实意味着您无法将引用对准其他任何地方,但您仍然可以从任一函数更改引用对象的内容。

The bigger problem you are going to have is in waiting until the callback has been called. 您将遇到的更大问题是等待调用回调。 This sort of wait-sleep might be good enough, but you may want to consider timeouts, threads, etc, depending on what you're trying to achieve. 这种等待睡眠可能已经足够好了,但您可能需要考虑超时,线程等,具体取决于您要实现的目标。

In addition, this all assumes that you are never going to call this twice on the connection. 此外,这一切都假设您永远不会在连接上调用两次。 Otherwise, you need to provide more info to us on your synchronization model. 否则,您需要在同步模型上向我们提供更多信息。

Here's some sample code: 这是一些示例代码:

public int getUserid(String username) {
        final ValueBox<Integer> userid = new ValueBox<Integer>();

        connection.call("getUserid", new Responder() {
                public void onResult(final int result) {
                        System.out.println("userid: " + result);
                        userId.setValue(result);
                        //how to assign received value to userid and return it?
                }
        }, username);

        //wait for response
        while (userid.isEmpty()) {
                try{
                        Thread.sleep(100);
                } catch (Exception e) {}
        }

      return userid.getValue();
}

The simplest change is to use something like java.util.concurrent.SynchronousQueue . 最简单的改变是使用类似java.util.concurrent.SynchronousQueue东西。 But possibly you want to provide an event driven interface yourself. 但是,您可能希望自己提供事件驱动的界面。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM