2012-01-05 1 views
5

Pourquoi SWING me force-t-il toujours à marquer certains objets comme définitifs? Puisque cela rend parfois les choses un peu difficiles, y a-t-il un moyen d'éviter cela?Swing et modificateur final

(EXEMPLE INCOMPLET) où il me force à marquer la variable IExchangeSource comme définitive:

public class MainFrame { 

private final JTextArea textArea = new JTextArea(); 


public static void main(final IExchangeSource s) { 
    EventQueue.invokeLater(new Runnable() { 

     @Override 
     public void run() { 
      new MainFrame(s); 
     } 
    }); 
} 
public MainFrame(final IExchangeSource s) { 
    //build gui 
    s.update(); 
+3

Pouvez-vous donner un exemple? Parlez-vous d'utiliser des variables d'une méthode environnante dans une classe interne anonyme? Parce qu'il n'y a rien dans Swing lui-même qui vous oblige à faire des variables 'final'. – Jesper

+2

Je parie que vous utilisez une classe interne anonyme. –

Répondre

18

Cela n'a rien à voir avec Swing, rien du tout. Vous devriez montrer votre code qui en a un exemple, mais vous utilisez probablement une classe interne, éventuellement une classe interne anonyme, et si vous les utilisez et essayez d'utiliser des variables dans la classe interne qui sont locales à une méthode englobante (ou autre bloc tel qu'un constructeur), alors vous êtes tenus de rendre ces variables finales ou de les promouvoir dans les champs de classe. Encore une fois, il s'agit d'une exigence Java, pas une exigence Swing.

Un exemple Swing:

public MyConstructor() { 
    final int localIntVar = 3; // this must be final 

    myJButton.addActionListener(new ActionListener() { 
     public void actionPerformed(ActionEvent evt) { 
     // because you use the local variable inside of an anon inner class 
     // not because this is a Swing application 
     System.out.println("localIntVar is " + localIntVar); 
     } 
    }); 
} 

et un exemple non-Swing:

public void myMethod() { 
    final String foo = "Hello"; // again it must be final if used in 
           // an anon inner class 

    new Thread(new Runnable() { 
     public void run() { 
     for (int i = 0; i < 10; i++) { 
      System.out.println(foo); 
      try { 
      Thread.sleep(1000); 
      } catch (Exception e) {} 

     } 
     } 
    }).start(); 
} 

Il y a plusieurs astuces pour éviter ceci:

  • Promouvoir la variable à un champ de classe , lui donnant une portée de classe.
  • La classe interne anonyme appelle une méthode de la classe externe. Mais alors, la variable devra toujours avoir une portée de classe.

Edit 2 Anthony Accioly posté une réponse avec un lien, mais pour des raisons inconnues supprimer sa réponse. Je voudrais poster son lien ici, mais j'adorerais le voir rouvrir sa réponse.

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

+0

Merci pour la réponse et oui j'utilisais une classe interne (voir l'exemple). Désolé de ne pas ajouter d'exemple au début. – Cemre

+0

@Cemre: s'il vous plaît voir modifier pour les solutions –

+0

@Cemre, que voulez-vous dire désolé de ne pas afficher un exemple? On vous a demandé par le passé d'afficher un SSCCE avec votre question. Un SSCCE devrait être inclus avec chaque question. – camickr