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

?
Foi útil?

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.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top