Ссылка на данные неконечной переменной внутри внутреннего класса - PullRequest
1 голос
/ 17 июня 2010

Я делаю программу в 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

Пожалуйста, предложите

Ответы [ 4 ]

7 голосов
/ 17 июня 2010

Даже если вам удастся преодолеть ошибку, функция не будет делать то, что вы намеревались сделать.Создаваемый вами обратный вызов будет уведомляться асинхронно об ответе, полученном от сервера, в то время как ваш метод populateRSSData () вернется немедленно.

Вам необходимо переосмыслить свой проект с учетом асинхронности.

РЕДАКТИРОВАТЬ: см. Привыкание к асинхронным вызовам

РЕДАКТИРОВАТЬ: Цитата из вышеупомянутой ссылки

Важно понимать, что код, который следует за вызовом вызова RPC, будет выполняться, пока выполняется фактическая передача данных на сервер.все еще в процессе.Хотя код внутри метода onSuccess () определен в строке с вызовом, он не будет выполняться до тех пор, пока вызывающий код не вернется обратно в основной цикл JavaScript, а сообщение о результате с сервера не вернется.

3 голосов
/ 17 июня 2010

Простой выход - объявите 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()]);
}
0 голосов
/ 17 июня 2010

Вам нужно использовать другую структуру данных для data, которая является изменяемой - вы можете изменить переменную final, но не назначать ее.Возможно, java.util.Vector или аналогичный подойдет вам здесь.

0 голосов
/ 17 июня 2010

Вам следует либо сделать переменную данных членом класса (если это возможно), либо обернуть ее каким-нибудь объектом, объявленным как final.

Переменные, используемые внутри локальных внутренних классов, должны быть объявлены как final. См. Также: метод local innerclasses для доступа к локальным переменным метода .

- EDIT -

Тахир Ахтар указал на нечто очень важное. Помимо общих моментов, которые я упомянул, в вашем дизайне есть недостаток - обратный вызов используется для асинхронного ответа. Ответ может прийти через много времени после завершения метода, поэтому результат еще не будет назначен.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...