返回来自回调的字符串 - Java

时间:2011-07-27 16:26:07

标签: java string callback return

有谁知道如何解决以下问题。我想从回调中返回一个String,但我只得到“最终的局部变量s不能被分配,因为它是在一个封闭的类型中定义的”,因为final。

 public String getConstraint(int indexFdg) {
    final String s;
    AsyncCallback<String> callback = new AsyncCallback<String>() {
        public void onFailure(Throwable caught) {
            caught.printStackTrace();
        }

        public void onSuccess(String result) {
            s = result;
        }
    };
    SpeicherService.Util.getInstance().getConstraint(indexFdg, callback);
    return s;
    }

2 个答案:

答案 0 :(得分:15)

异步回调的重点是在将来的某个时间通知您异步发生的事情。如果在方法运行完毕后将设置<{1}},则无法从s返回getConstraint

在处理异步回调时,您必须重新考虑程序的流程。而不是getConstraint返回值,而应该通过回调调用使用该值的代码。

作为一个简单(不完整)的例子,你需要改变这个:

 String s = getConstraint();
 someGuiLabel.setText(s);

这样的事情:

 myCallback = new AsyncCallback<String>() {
     public void onSuccess(String result) {
         someGuiLabel.setText(result);
     }
 }
 fetchConstraintAsynchronously(myCallback);

修改

一种流行的替代方案是 future 的概念。未来是一个对象,您可以立即返回,但在将来的某个时刻只会有一个值。它是一个容器,您只需要在要求它时等待值。

您可以考虑为持有干洗衣服的机票持有未来。你立刻得到了票,可以把它放在你的钱包里,交给朋友......但是一旦你需要换一件真正的套装,你需要等到套装准备就绪。

Java有这样一个类(Future<V>),ExecutorService API广泛使用。

答案 1 :(得分:3)

另一种解决方法是定义一个名为SyncResult

的新类
public class SyncResult {
    private static final long TIMEOUT = 20000L;
    private String result;

    public String getResult() {
        long startTimeMillis = System.currentTimeMillis();
        while (result == null && System.currentTimeMillis() - startTimeMillis < TIMEOUT) {
            synchronized (this) {
                try {
                    wait(TIMEOUT);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
        return result;
    }

    public void setResult(String result) {
        this.result = result;
        synchronized (this) {
            notify();
        }
    }
}

然后将您的代码更改为此

public String getConstraint(int indexFdg) {
    final SyncResult syncResult = new SyncResult();
    AsyncCallback<String> callback = new AsyncCallback<String>() {
        public void onFailure(Throwable caught) {
            caught.printStackTrace();
        }

        public void onSuccess(String result) {
            syncResult.setResult(result);
        }
    };
    SpeicherService.Util.getInstance().getConstraint(indexFdg, callback);
    return syncResult.getResult();
}

在调用getResult()方法或达到setResult(String)之前,TIMEOUT方法将被屏蔽。