2
respostas

loop for acessar variavel de fora do escopo

while (it.hasNext()) {
    System.out.println(it.next());
} //legado
for(Letra letra : letras){
    System.out.println(letra);
} //legado
letras.forEach(letra -> {
    System.out.println(letra);
});

As formas legadas (acredito que sejam essas marcadas no código) de fazer o loop for permitem acessar variaveis de fora do escopo. Como fazer isso na maneira mais atual?

2 respostas

Olá Antônio.

Acredito que com a expressão "variáveis de fora do escopo" você quis dizer variáveis que são declaradas fora do laço de repetição, mas são acessíveis nele. Correto?

Para uso em expressões lambdas, como essa última do forEach que você exemplificou, é possível acessar somente:

  • Variáveis estáticas;
  • Variáveis de instância;
  • Parâmetros de métodos "efetivamente final";
  • Variáveis locais "efetivamente final".

No caso das "efetivamente final", o parâmetro ou variável não pode receber outra atribuição, mesmo em linhas depois de seu uso no lambda. Se acontecer isso, deixa de ser "efetivamente final" e o compilador reclama.

Exemplo de efetivamente final:

void metodo (Integer param1, Integer param2, List<Integer> lista) {
    // linha abaixo compila, pois param1 é efetivamente final
    lista.forEach(itemLista -> System.out.println(itemLista + param1)); 
    // linha abaixo não compila, pois param2 não é efetivamente final
    lista.forEach(itemLista -> System.out.println(itemLista + param2)); 

    // essa atribuição, mesmo depois do uso no lambda, faz com que o param2 deixe de ser efetivamente final
    param2 = 2;
}

Muito boa sua observação. É bem próximo do que eu estou perguntando. É uma situação bem frequente. Abaixo, sem colocar como final, qual seria a solução para o novo forEach?

        Integer param1=0;
        List<String> letras = new ArrayList();
        for(String letra : letras){
            param1 +=1; // compila
        }
        letras.forEach(letra -> {
            System.out.println(letra);
            param1 +=1; // não compila, qual substituto?
        });