Local variable referenced from an inner class must be final or effectively final

Bom dia pessoal, estou com o seguinte problema usando o código abaixo.
Mesmo colocando o tipo do campo para final ele continua dando o erro.

private final String opcao = null;

A ideia do código abaixo é o úsuario a partir de um botão chamar a função passando a opção como parametro, assim para cada item a ser escolhido o usuario iria enviar uma solicitação.

Porém eu não estou conseguindo limpar essa variavel, então cada vez que entra na rotina ele sempre seleciona o último valor que o úsuario digitou.

public void ContinuaPinpadSec(TelaPrincipal tela, String opcao) {  
  try {  
    status = clisitef.continuaFuncaoSiTefInterativo ();
    int delay3 = 1000;
    int interval3 = 1000;
    
    if (status == 10000) {
      // while (status == 10000)
      // {
      timer4.scheduleAtFixedRate(new TimerTask() {
        @Override
        public void run() { 
          status = clisitef.continuaFuncaoSiTefInterativo();
          int proximoComando;
          String texto = "";
          BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
          
          if (status == 10000) {
            // Aqui deve-se colocar o tratamento de cada tipo de ProximoComando
            System.out.println ("ProximoComando = " + clisitef.getProximoComando ());
            System.out.println ("TipoCampo = " + clisitef.getTipoCampo ());
            System.out.println ("TamanhoMinimo = " + clisitef.getTamanhoMinimo ());
            System.out.println ("TamanhoMaximo = " + clisitef.getTamanhoMaximo ());
            System.out.println ("Buffer = " + clisitef.getBuffer ());
            String tipocampo = String.valueOf(clisitef.getTipoCampo());
            System.out.println ("opcao = " + opcao);
            
            if (
              !clisitef.getBuffer().trim().equals("") 
              && (
                tipocampo.trim().equals("-1") 
                || tipocampo.trim().equals("505") 
                || tipocampo.trim().equals("5013") 
                || tipocampo.trim().equals("500")
              )
            ) {
              texto += System.lineSeparator();
              String[] split = clisitef.getBuffer().split(";");
              
              for (int x = 0; x < split.length; x++) {
                texto = split[x] + System.lineSeparator();
              }
              
              tela.getTela().setText(texto + System.lineSeparator());
            }
            
            proximoComando = clisitef.getProximoComando();
            
            if (proximoComando >= 20 && proximoComando != 23 && proximoComando != 22) {
              // clisitef.setBuffer(in.readLine());
              clisitef.setBuffer(opcao);
            }
            
            int tamanhoOpcao = opcao.length();
            
            if (tamanhoOpcao >= 0) {
              opcao = null;
            }
          }
          
          if (status != 10000) {
            System.out.println ("ContinuaFuncaoSiTefInterativo retornou " + status);
            System.out.println ("Trn pendentes: " + clisitef.obtemQuantidadeTransacoesPendentes (pedido,data_pedido));
            clisitef.finalizaTransacaoSiTefInterativo ((short) 1,pedido,data_pedido, "102000");
          }
        }
      }, delay3, interval3);
    }
    
    if (status != 10000) {
      System.out.println ("ContinuaFuncaoSiTefInterativo retornou " + status);
      System.out.println ("Trn pendentes: " + clisitef.obtemQuantidadeTransacoesPendentes (pedido,data_pedido));
      clisitef.finalizaTransacaoSiTefInterativo ((short) 1,pedido,data_pedido, "102000");
    }
  } catch (Exception ex) {
    tela.getTela().setText("Problema na DLL" + System.lineSeparator());
    System.out.println("Erro "+clisitef.getBuffer ());
  }
}

Variáveis definidas com final não podem sofrer uma mudança de referência, o valor com o qual você inicializa ela deve ser o mesmo durante todo o fluxo!

Na verdade o problema dele é justamente o contrário, ele tem o método ContinuaPinpadSec, dentro desse método ele tem algumas variáveis locais, como o status e esse status ele está tentando acessar de dentro de uma innerclass que foi declarada nesse método.

Uma innerclass dentro de um método, só consegue acessar as variáveis locais final do método.

Se ele mudar o status para final, deve resolver.

Na verdade @staroski e @Jonathan_Medeiros o fluxo dessa aplicação é o seguinte:

Existe um botão que no evento dele é chamada a função ContinuaPinpadSec.
PinPad pinpad = new PinPad();
pinpad.ContinuaPinpadSec(this, opcao);

Como parametro fica o opção, porém gosstaria de ao final do evento esse campo opção ficasse = “” ou null, pois como o fluxo continua se ele tiver algum valor interfere nas outras etapas que o úsuario vai acessar, como exemplo:
vai aparecer para o úsuario digitar:
1 - Cartão Crédito
2- Cartão Débito
o usuario seleciona 1 como exemplo
depois vai aparecer:
1 - A vista
2 - Parcelado

Como a variavel não é limpa ela segue como 1, então já pula essa segunda etapa sem escolha alguma do usuario.

Não sei se ficou claro, mas esse é o problema.

Agradeço as respostas acima.

Então seria assim, após essa etapa:
clisitef.setBuffer(opcao);

o campo opção receberia “” ou null e ai quando passasse novamente eu perguntaria:
int tamanhoOpcao = opcao.length();
if( tamanhoOpcao > 0){
clisitef.setBuffer(opcao);
System.out.println ("Tamanho = " + tamanhoOpcao);
}
else{
System.out.println ("Tamanho Zerado= " + tamanhoOpcao);
}

Alterar a referência de uma variável local ou parâmetro, só tem efeito no método onde ela foi declarada.

Se você depende da alteração feita dentro do seu método ContinuaPinpadSec você pode fazer esse método retornar o valor alterado, aí sua chamada ficaria assim:

PinPad pinpad = new PinPad();
opcao = pinpad.ContinuaPinpadSec(this, opcao);

@staroski no caso o problema não seria o retorno, mas sim que como o método ContinuaPinpadSec tem um timer, se o valor de opção for igual ao anterior ele fica passando pela próxima escolha sem o úsuario ter digitado nada.

Exemplo:

Aparece em tela:
1 - cartão de débito
2 - Cartão de Crédito

O usuario vai escolher a opção 2 por exemplo, então o campo opção fica = 2 e o timer rodando, pois assim ele segue o processo e vai para a proxima opção, que fica assim:

1 - A vista
2 - Parcelado

Como o valor de opção não é limpo a escolha vai ser 2, pois ele entende que já tem um valor na variavel.

Então eu gostaria de quando acabasse o primeiro processo a variavel ficasse limpa.

Deu para entender?