Java 引用内部类中的非最终变量数据

Java 引用内部类中的非最终变量数据,java,gwt,Java,Gwt,我正在用GWT做一个程序。这是我遇到问题的片段 private String[] populateRSSData() { 1==>> String[] data = null; try { new RequestBuilder(RequestBuilder.GET, "../database.php?action=populaterss").sendRequest(null, new RequestCallback() { @Over

我正在用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==>

我得到的错误

不能引用在不同方法RSS\u Manager.java中定义的内部类中的非最终变量数据


请建议

您要么将数据变量设为类成员(如果可能),要么用声明为final的对象将其包装起来

局部内部类中使用的变量必须声明为final。另见:

--编辑--


塔希尔·阿赫塔指出了一些非常重要的事情。除了我提到的一般要点之外,您的设计中还有一个缺陷——回调用于异步响应。响应可能在方法终止后很长时间内到达,因此结果还不会被赋值。

您应该将数据变量设为类成员(如果可能),或者用声明为final的某个对象将其包装起来

局部内部类中使用的变量必须声明为final。另见:

--编辑--


塔希尔·阿赫塔指出了一些非常重要的事情。除了我提到的一般要点之外,您的设计中还有一个缺陷——回调用于异步响应。响应可能在方法终止后很长时间内到达,因此结果还不会被分配。

您需要为可变的
数据使用不同的数据结构-您可以修改
最终的
变量,但不能分配给它。也许
java.util.Vector
或类似的变量适合您的需要。

您需要为可变的
数据使用不同的数据结构-您可以修改
final
变量,但不能将其赋值。也许一个
java.util.Vector
或类似的函数可以满足您的需要。

即使您设法克服了错误,函数也不会执行您希望它执行的操作。 当方法populateRSSData()将立即返回时,您正在创建的回调将收到从服务器接收的响应的异步通知

您需要重新考虑您的设计,将异步性考虑在内

编辑:请参见

编辑: 引用上述链接

需要理解的重要问题是,RPC调用之后的代码将在到服务器的实际往返过程仍在进行时执行。尽管onSuccess()方法中的代码是与调用内联定义的,但在调用代码返回JavaScript主循环且服务器返回结果消息之前,不会执行该方法


即使您设法克服了错误,函数也不会执行您希望它执行的操作。 当方法populateRSSData()将立即返回时,您正在创建的回调将收到从服务器接收的响应的异步通知

您需要重新考虑您的设计,将异步性考虑在内

编辑:请参见

编辑: 引用上述链接

需要理解的重要问题是,RPC调用之后的代码将在到服务器的实际往返过程仍在进行时执行。尽管onSuccess()方法中的代码是与调用内联定义的,但在调用代码返回JavaScript主循环且服务器返回结果消息之前,不会执行该方法


一个简单的解决方法-将
数据
声明为字符串列表,并使列表成为最终列表。您始终可以将元素添加到最终列表中(只是无法将其他列表分配给最终变量)

因此,对于您的代码:

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()]);
}
私有字符串[]populateRSSData(){
最终列表数据=新的ArrayList();
试一试{
新建RequestBuilder(RequestBuilder.GET,
“./database.php?action=populaterss”).sendRequest(null,
新的RequestCallback(){
@凌驾
收到响应时公共无效(请求,
回应(回应){
data.addAll(Arrays.asList(response.getText().split(“~”));
}
@凌驾
公共void onError(请求,可丢弃异常){
Window.alert(exception.getMessage());
}
});
}捕获(请求异常e){
Window.alert(如getMessage());
}
返回data.toArray(新字符串[data.size()]);
}

一个简单的解决方法-将
数据声明为字符串列表,并使列表成为最终列表。您始终可以将元素添加到最终列表中(您只是无法为最终变量指定其他列表)

因此,对于您的代码:

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()]);
}
私有字符串[]populateRSSData(){
最终列表数据=新的ArrayList();
试一试{
新建RequestBuilder(RequestBuilder.GET,
“./database.php?action=populaterss”).sendRequest(null,
新的RequestCallback(){
@凌驾
收到响应时公共无效(请求,
回应(回应){
data.addAll(Arrays.asList(response.getText().split(“~”));
}
@凌驾
公共void onError(请求,可丢弃异常){
Window.alert(exception.getMessage());
}
});
}捕获(请求异常e){
Window.alert(如getMessage());
}
返回data.toArray(新字符串[data.size()]);
}

+1 Tahir是正确的。您的方法将始终返回null,因为异步调用的结果尚未分配…请在onResponseReceived()中对数据执行需要执行的操作;)Din不要从这个角度思考。感谢Tahir,我需要重新设计结构+1 Tahir是正确的。您的方法将始终返回null,因为异步调用的结果尚未分配…在onResponseReceived()中执行您需要对数据执行的操作;)Din不要从这个角度思考。谢谢塔希尔,我需要重新设计stru