/ / Por que o compilador está aceitando uma variável não final na classe interna? - java, android, erros de compilação

Por que o compilador está aceitando uma variável não final na classe interna? - java, android, erros de compilador

Estou criando um MediaPlayer com seekbar.Here, mp é um objeto MediaPlayer e buscador é um objeto de barra de busca criado na classe MainActivity.

Meu entendimento é que apenas os membros finais são acessíveis à classe interna anônima. como o executável acessa esses objetos(mp e candidato).

     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: O código funciona perfeitamente. Obrigado pela ajuda.

Respostas:

4 para resposta № 1

Isso acontece, porque existe algo chamado efetivamente final.

jls-8.1.3:

Qualquer variável local, parâmetro formal ouO parâmetro de exceção usado, mas não declarado em uma classe interna, deve ser declarado final ou efetivamente final (§4.12.4), ou ocorre um erro em tempo de compilação quando o uso é tentado.

jls-4.12.4:

Se uma variável for efetivamente final, adicione o valorO modificador final de sua declaração não apresentará erros em tempo de compilação. Por outro lado, uma variável local ou parâmetro declarado final em um programa válido se torna efetivamente final se o modificador final for removido.

Quando a variável é definida apenas uma vez e é usada em uma classe interna, o compilador transforma o modificador da variável em final.

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

O código acima, quando compilado, produzirá esse código abaixo. Você pode ver que o compilador altera o modificador de value para 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);
}
};
}
}

Mas, se você alterar o valor da variável (consulte o código abaixo), ela não será compilada, porque o compilador sabe que não é uma variável efetivamente final:

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