开发者

Referring to a non-final variable data inside an inner class

Im doing a program in GWT. Here is the snippet where Im having problem

 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;
 }

Now the problem arises that I get an error that the variable 1==>> data should be declared final. But if I declare it as final then i cannot store the datas in 2==>>

The error i get

Cannot refer to a non-final variable data inside an开发者_高级运维 inner class defined in a different method RSS_Manager.java

Please suggest


Even if you manage to get over the error, the function will not do what you intend it to do. The callback you are creating will be notified asynchronously of the response received from server while your method populateRSSData() will return immediately.

You need to rethink your design taking the asynchrony into account.

EDIT: see Getting Used to Asynchronous Calls

EDIT: Quote from the above link

The important issue to understand is that that the code that follows the RPC call invocation will be executed while the actual round trip to the server is still in progress. Although the code inside the onSuccess() method is defined inline with the call, it will not be executed until both the calling code returns back to the JavaScript main loop, and the result message from the server returns.


An easy way out - declare data as a list of Strings and make the list final. You can always add elements to final list (you just can`t assign a different list to the final variable).

So for your code:

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()]);
}


You need to use a different data structure for data which is mutable - you can modify a final variable, but not assign to it. Perhaps a java.util.Vector or similar would suit your needs here.


You should either make the data variable a class member (if possible), or wrap it with some object declared as final.

Variables used inside local inner classes must be declared as final. See also: method local innerclasses accessing the local variables of the method.

--EDIT--

Tahir Akhtar pointed out something very important. Besides the general points I mentioned, there is a flaw in your design - the callback is used for asynchronous response. The response may arrive long after the method terminates, so the result will not be assigned yet.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜