2012-01-05 9 views
5

¿Por qué SWING siempre me obliga a marcar algunos objetos en particular como finales? Dado que esto a veces hace las cosas un poco difíciles, ¿hay alguna manera de evitar esto?Modificador de oscilación y final

(Ejemplo incompleto) en el que me obliga a marcar la variable IExchangeSource como definitiva:

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

¿Puede dar un ejemplo? ¿Estás hablando de usar variables de un método circundante en una clase interna anónima? Porque no hay nada en Swing que te obligue a hacer variables 'final'. – Jesper

+2

Apuesto a que estás usando una clase interna anónima. –

Respuesta

18

Esto tiene nada que ver con Swing, nada en absoluto. Debería mostrar el código que tiene un ejemplo de esto, pero es probable que esté utilizando una clase interna, posiblemente una clase interna anónima, y ​​si los usa y trata de usar variables dentro de la clase interna que son locales para un método envolvente (o otro bloque, como un constructor), entonces se le solicita que haga que estas variables sean definitivas o las promocione a los campos de clase. De nuevo, este es un requisito Java, no un requisito Swing.

Un ejemplo de 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); 
     } 
    }); 
} 

y un ejemplo no-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(); 
} 

Hay varios trucos para evitar esto:

  • Promover la variable a un campo de clase , dándole alcance de clase.
  • Haz que la clase anónima invoque un método de la clase externa. Pero entonces, la variable aún necesitará tener alcance de clase.

Editar 2 Anthony Accioly registró una respuesta con un gran enlace, pero por razones desconocidas suprimen la respuesta. Me gustaría publicar su enlace aquí, pero me encantaría verlo volver a abrir su respuesta.

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

+0

Gracias por la respuesta y sí, estaba usando una clase interna (ver el ejemplo). Perdón por no agregar un ejemplo al principio. – Cemre

+0

@Cemre: consulte la edición de soluciones –

+0

@Cemre, ¿qué quiere decir lo siento por no publicar un ejemplo? En el pasado se le ha pedido que publique un SSCCE con su pregunta. Se debe incluir un SSCCE con cada pregunta. – camickr