我在GWT做一个程序。这是我有问题的片段
private String[] populateRSSData() {
1==>> String[] data = null;
try {
new RequestBuilder(RequestBuilder.GET,
"../database.php?action=populaterss").sendRequest(null,
new RequestCallback() {
@Override
public void onResponseReceived(Request request,
Response response) {
2==>> data=response.getText().split("~");
}
@Override
public void onError(Request request, Throwable exception) {
Window.alert(exception.getMessage());
}
});
} catch (RequestException e) {
Window.alert(e.getMessage());
}
return data;
}
现在出现的问题是,我收到一个错误,即变量1==>>
data
应该声明为final
。但如果我将其声明为final
,那么我无法将数据存储在2==>>
我得到的错误
Cannot refer to a non-final variable data inside an inner class defined in a different method RSS_Manager.java
请建议
答案 0 :(得分:7)
即使您设法克服错误,该功能也不会按照您的意图执行。 您正在创建的回调将以异步方式通知从服务器收到的响应,而您的方法populateRSSData()将立即返回。
您需要重新考虑考虑异步的设计。
编辑:请参阅Getting Used to Asynchronous Calls
修改强> 从上面的链接引用
要理解的重要问题是,在执行到服务器的实际往返过程中,将执行RPC调用调用之后的代码。虽然onSuccess()方法中的代码是与调用内联定义的,但是在调用代码返回到JavaScript主循环并且来自服务器的结果消息返回之前,它不会被执行。
答案 1 :(得分:3)
一个简单的方法 - 将data
声明为字符串列表并使列表最终。您始终可以将元素添加到最终列表中(您只能为最终变量指定不同的列表)。
所以对于你的代码:
private String[] populateRSSData() {
final List<String> data = new ArrayList<String>();
try {
new RequestBuilder(RequestBuilder.GET,
"../database.php?action=populaterss").sendRequest(null,
new RequestCallback() {
@Override
public void onResponseReceived(Request request,
Response response) {
data.addAll(Arrays.asList(response.getText().split("~"));
}
@Override
public void onError(Request request, Throwable exception) {
Window.alert(exception.getMessage());
}
});
} catch (RequestException e) {
Window.alert(e.getMessage());
}
return data.toArray(new String[data.size()]);
}
答案 2 :(得分:0)
您应该将数据变量设为类成员(如果可能),或者将其包装为声明为final的对象。
本地内部类中使用的变量必须声明为final。另见:method local innerclasses accessing the local variables of the method。
- 编辑 -
Tahir Akhtar指出一些非常重要的事情。除了我提到的一般要点之外,你的设计还有一个缺陷 - 回调用于异步响应。响应可能在方法终止后很长时间到达,因此结果将不会被分配。答案 3 :(得分:0)
您需要为data
使用可变的不同数据结构 - 您可以修改final
变量,但不能分配给它。也许java.util.Vector
或类似的东西可以满足您的需求。