criação de variáveis ??final dentro de um loop
Pergunta
Isso é permitido em java:
for(int i=0;i<5;i++){
final int myFinalVariable = i;
}
A palavra-chave da minha pergunta é final
. É permitido fazer uma variável final que muda com cada execução do loop? Fiquei me perguntando isso porque última diz que você não pode alterar o valor da variável (chamando única myFinalVariable = i
), mas eu estou redefinindo a variável inteiro com final int
.
São eles duas variáveis ??completamente diferentes apenas com o mesmo nome - com a variável da execução anterior do loop já descendo a estrada para o coletor de lixo
?Solução
Sim, é permitido. Os meios final
palavra-chave que você não pode mudar o valor da variável dentro de seu escopo . Para o seu exemplo loop, você pode pensar da variável sair do escopo na parte inferior do loop, em seguida, voltar para o escopo com um novo valor no topo do loop. Atribuindo à variável dentro do ciclo não irá funcionar.
Outras dicas
Você está certo, para cada iteração do loop, você está criando uma nova variável. As variáveis ??compartilham o mesmo nome, mas isso é bom porque eles não estão no mesmo escopo. Próxima exemplo seria não trabalho:
final int myFinalVariable = 0;
for(int i=0;i<5;i++){
myFinalVariable = i;
}
Uma variável é apenas um local na pilha. Tente manter suas variáveis ??com que alcance uma pequena quanto possível e tentar fazê-los final. No entanto escopo e final são coisas de código apenas de origem ... de uma geração de código / ponto de vista VM eles realmente não importa a todos.
No seu exemplo específico, usando "int" nenhum lixo é criado. No entanto, se foram objetos que está sendo criado, em seguida, para ambos os casos a quantidade de lixo e quando o lixo seriam elegíveis para a limpeza seria idêntico.
Tome o seguinte código:
public class X
{
public static void main(final String[] argv)
{
foo();
bar();
}
private static void foo()
{
for(int i=0;i<5;i++)
{
final int myFinalVariable = i;
}
}
private static void bar()
{
for(int i=0;i<5;i++)
{
int myFinalVariable = i;
}
}
}
O compilador produz código de bytes idêntico para cada método:
public class X extends java.lang.Object{
public X();
Code:
0: aload_0
1: invokespecial #1; //Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: invokestatic #2; //Method foo:()V
3: invokestatic #3; //Method bar:()V
6: return
private static void foo();
Code:
0: iconst_0
1: istore_0
2: iload_0
3: iconst_5
4: if_icmpge 15
7: iload_0
8: istore_1
9: iinc 0, 1
12: goto 2
15: return
private static void bar();
Code:
0: iconst_0
1: istore_0
2: iload_0
3: iconst_5
4: if_icmpge 15
7: iload_0
8: istore_1
9: iinc 0, 1
12: goto 2
15: return
}
Como adicionar um outro método que declara a variável fora do loop dará bytecode ligeiramente diferente devido à ordem que as variáveis ??são declaradas). Note-se que esta versão da variável não pode ser feita final. Esta última versão não é a melhor maneira (a última variável dentro do ciclo é a melhor se você pode fazê-lo):
private static void car()
{
int myFinalVariable;
for(int i=0;i<5;i++)
{
myFinalVariable = i;
}
}
private static void car();
Code:
0: iconst_0
1: istore_1
2: iload_1
3: iconst_5
4: if_icmpge 15
7: iload_1
8: istore_0
9: iinc 1, 1
12: goto 2
15: return
}
Como respondeu: Sim, você pode realmente marcar as variáveis ??em um loop como 'final'. Aqui é o efeito de fazê-lo (Java 7, Eclipse Indigo, Mac OS X Lion).
for ( int i = 0; i < 5; i++ ) {
// With 'final' you cannot assign a new value.
final int myFinalVariable = i; // Gets 0, 1, 2, 3, or 4 on each iteration.
myFinalVariable = 7; // Compiler error: The final local variable myFinalVariable cannot be assigned.
// Without 'final' you can assign a new value.
int myNotFinalVariable = i; // Gets 0, 1, 2, 3, or 4 on each iteration.
myNotFinalVariable = 7; // Compiler is OK with re-assignment of variable's value.
}
variável declarada dentro do loop tem o escopo apenas até o único execução do loop.
declarando a variável como final dentro do ciclo faz com que a diferença para a variável no lado da laçada, mas se declarar a variável fora do loop com modificador final, então o valor atribuído ao tipo primitivo ou objecto atribuído a variável de referência não pode ser alterado.
No exemplo abaixo não há nenhum problema com os dois primeiros lacetes ambos os lacetes dão mesma saída, mas o terceiro laço dá um erro de tempo de compilação.
teste de classe pública {
public static void main(String[] args) {
for (int i = 0; i < 5; i++) {
final int j= i;
System.out.println(j);
}
for (int i = 0; i < 5; i++) {
int j= i;
System.out.println(j);
}
final int j;
for (int i = 0; i < 5; i++) {
j= i;
System.out.println(j);
}
}
}
Por favor, me corrija se eu estiver errado.