/ / ¿Por qué el compilador acepta una variable no final en la clase interna? - Java, Android, errores del compilador

¿Por qué el compilador acepta una variable no final en la clase interna? - java, android, errores de compilación

Estoy creando un MediaPlayer con seekbar.Aquí, mp es un objeto MediaPlayer y buscador es un objeto seekbar creado en la clase MainActivity.

Mi entendimiento es que solo los miembros finales son accesibles a la clase interna anónima. Luego ¿Cómo se puede acceder a esos objetos?(mp y buscador).

     h = new Handler();  // create a handler for the MainActivity

//create a runnable activity to change the progress of seekbar in MainThread for every 1 sec
Runnable r = new Runnable() {
@Override
public void run() {
if (mp != null) {
seeker.setProgress(mp.getCurrentPosition() / 1000);
}
h.postDelayed(this, 1000);
}
};

this.runOnUiThread(r);

Nota: El código funciona perfectamente. Gracias por la ayuda.

Respuestas

4 para la respuesta № 1

Sucede, porque hay algo que se llama efectivamente final.

jls-8.1.3:

Cualquier variable local, parámetro formal, oel parámetro de excepción utilizado pero no declarado en una clase interna debe ser declarado final o ser efectivamente final (§4.12.4), o se produce un error en tiempo de compilación cuando se intenta el uso.

jls-4.12.4:

Si una variable es efectivamente final, agregando elEl modificador final de su declaración no introducirá ningún error en tiempo de compilación. A la inversa, una variable o parámetro local que se declara final en un programa válido se convierte efectivamente en final si se elimina el modificador final.

Cuando la variable solo se establece una vez y se usa en una clase interna, el compilador convierte el modificador de variable en final.

Considera este código Tests.java:

public class Tests  {
public static void main(String[] args) throws Throwable {
String value = "Hello";

Runnable runnable = new Runnable() {
@Override
public void run() {
System.out.println(value);
}
};
}
}

El código anterior, cuando se compila, producirá este código a continuación. ¿Puedes ver que el compilador cambia el modificador de value a final?

Tests.class (decodificado):

public class Tests {
public Tests() {
}

public static void main(String[] args) throws Throwable {
final String value = "Hello";
Runnable var10000 = new Runnable() {
public void run() {
System.out.println(value);
}
};
}
}

Pero, si cambia el valor de la variable (vea el código a continuación), no se compilará, porque el compilador sabe que no es una variable final efectiva:

public class Tests  {
public static void main(String[] args) throws Throwable {
String value = "Hello";
value = "world";

Runnable runnable = new Runnable() {
@Override
public void run() {
System.out.println(value);
}
};
}
}