La variable local final no se puede asignar

Tengo una serie de asientos, y el conjunto tiene dos cadenas (seleccionada y vacía). Al hacer clic con el mouse, quiero atravesar la matriz y encontrar el asiento seleccionado. Cuando presiono el botón, dice:

La variable local final seatno no se puede asignar, ya que se define en un tipo adjunto.

JButton btnContinue = new JButton("Next"); btnContinue.addMouseListener(new MouseAdapter() { public void mouseClicked(MouseEvent arg0) { for(int x=0;x<17;x++){ if(anArray[x]=="selected"){ seatno = anArray[x]; } } data page=new data(newfrom,newto,newtime,date2,seatno); page.setVisible(true); setVisible(false); } }); btnContinue.setBounds(358, 227, 62, 23); contentPane.add(btnContinue); 

El punto es que las variables locales del método del tipo adjunto se copian a instancias de clases anónimas (esto se debe a problemas con el marco de activación, pero no profundizaré en los detalles ya que esto no es realmente relevante para la pregunta), que Es por eso que deben ser definitivas, porque la variable en la instancia de tipo nested ya no es la misma.

Entonces, aquí está el primer ejemplo:

 void foo() { int a = 3; new Runnable() { @Override public void run() { a += 3; } }; } 

Esto no se comstack, porque no se puede hacer referencia a una variable no final en un método de clase anónimo. Cuando agrega un modificador final a la statement de a , el valor de a se copiará en la instancia creada de la clase anónima que ha definido. Sin embargo, no se le permitirá cambiar el valor de a , porque los cambios no serían visibles para el método donde se declaró a.

Sin embargo, las clases anónimas no son estáticas, es decir, tienen una referencia a la instancia adjunta (a menos que el método donde se declaran sea estático) que puede usar para modificar las variables de la instancia adjunta:

 int a = 3; void foo() { new Runnable() { @Override public void run() { a += 3; } }; } 

Este ejemplo se comstack y se incrementará en 3 cada vez que se llame al método run() de la instancia de la clase anónima. (En este ejemplo, nunca se llama, pero es solo un ejemplo).

Por lo tanto, para resumir, debe convertir la variable seatno de una variable seatno de método a una variable de instancia del tipo circundante. O, si aún es así, debe eliminar el modificador final ya que las variables finales solo se pueden asignar una vez.

Actualización: en Java 8, se introduce el concepto de variables finales efectivas (ver Especificación del lenguaje Java ). Sin embargo, en el primer ejemplo de esta publicación, la variable a se asigna varias veces, lo que impide que sea efectivamente definitiva. Esto significa que este ejemplo aún no se comstack con Java 8. (El error de comstackción es “La variable local a definida en un ámbito adjunto debe ser final o efectivamente final”)

En lugar de definir una variable de miembro de clase, también puede usar una variable mutable para lograr lo mismo.

 void foo() { final MutableInt a = new MutableInt(3); new Runnable() { @Override public void run() { a.add(3); } }; } 

Como MutableInt no es un tipo primitivo (por lo tanto, se pasa por referencia) y puede reasignarse, esto funciona.

Una variable final no puede cambiar su valor (es similar a const desde C / C ++).

Probablemente desee convertirlo en un campo de una clase (sin la palabra clave final del curso), no como una variable local dentro de una función.

Recientemente me enfrenté a un problema similar. En mi caso, fue más fácil crear la matriz final (o colección) y agregar la variable, que quería cambiar dentro de la clase anónima, a esta matriz, como se muestra a continuación.

  int a = 3; final int[] array = new int[1]; array[0] = a; new Runnable() { @Override public void run() { array[0] += 3; } }; 

Sin conocer la statement de seatno , sugiero introducir una nueva variable en el método mouseClicked() que no es definitiva y realiza el mismo trabajo que seatno actualmente, ya que la variable solo parece usarse dentro de ese método.

Por cierto: capitalice sus nombres de clase (los data deberían ser Data ). Se verá mucho más claro.

Asegúrate de que tu variable no tenga el modificador final .

 //final, can be set only when the object is created. private final String seatno; //no final modifier, the value can be set every time you "want" private String seatno; 

Además, para comparar cadenas, debe usar equals :

 if(anArray[x].equals("selected"))