2010-06-17 5 views
1

Je fais un programme dans GWT. Voici l'extrait où Im ayant problèmeRéférence à une variable non-finale dans une classe interne

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

Maintenant, le problème se pose que je reçois une erreur que la variable 1==>>data doit être déclarée final. Mais si je déclare comme final alors je ne peux pas stocker les données dans 2==>>

L'erreur que je reçois

Cannot refer to a non-final variable data inside an inner class defined in a different method RSS_Manager.java

S'il vous plaît suggèrent

Répondre

7

Même si vous parvenez à surmonter l'erreur, la fonction ne fera pas ce que vous avez l'intention de faire. Le rappel que vous créez sera notifié de manière asynchrone de la réponse reçue du serveur alors que votre méthode populateRSSData() sera immédiatement renvoyée.

Vous devez repenser votre conception en tenant compte de l'asynchronie.

EDIT: voir Getting Used to Asynchronous Calls

EDIT: Citation du lien ci-dessus

La question importante à comprendre est que le code qui suit l'invocation d'appel RPC sera exécuté en l'aller-retour actuel vers le serveur est toujours en cours. Bien que le code de la méthode onSuccess() soit défini en ligne avec l'appel, il ne sera pas exécuté tant que le code appelant ne reviendra pas à la boucle principale JavaScript et que le message de résultat du serveur ne sera pas renvoyé.

+0

+1 Tahir est droite.Votre méthode renverra toujours null parce que le résultat de l'appel asynchrone n'a pas encore été assigné ... Faites ce que vous devez faire avec des données dans onResponseReceived();) – Bogdan

+0

dint pensez de cette perspective. Merci Tahir, j'ai besoin de refaire la structure – Sam

0

Vous devez soit faire la variable de données membre de classe (si possible), ou envelopper avec un objet déclaré comme final.

Les variables utilisées dans les classes internes locales doivent être déclarées comme définitives. Voir aussi: method local innerclasses accessing the local variables of the method.

--EDIT--

Tahir Akhtar a souligné un point très important. Outre les points généraux que j'ai mentionnés, il y a une faille dans votre conception - le rappel est utilisé pour la réponse asynchrone. La réponse peut arriver longtemps après la fin de la méthode, de sorte que le résultat ne sera pas encore attribué.

0

Vous devez utiliser une structure de données différente pour data qui est modifiable - vous pouvez modifier une variable final, mais ne pas lui affecter. Peut-être un java.util.Vector ou similaire conviendrait à vos besoins ici.

3

Un moyen facile de sortir - déclarer data comme une liste de chaînes et rendre la liste finale. Vous pouvez toujours ajouter des éléments à la liste finale (vous ne pouvez pas affecter une liste différente à la variable finale).

Donc, pour votre 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()]); 
} 
Questions connexes