Olá desenvolvedores, hoje iremos falar sobre soluções para o NullPointerException. Este que é sem qualquer sombra de dúvida a exceção mais comum na vida de um programador.

Já vimos por aqui que um NullPointerException é lançado quando tentamos manipular um objeto nulo. Isto é, acessar seja uma propriedade, métodos ou atributos de um objeto, mas sem tê-lo instanciado. Sem que ele tenha sido criado. Em síntese, isso significa que este objeto está nulo, ou seja, não possui um valor definido.

Sabemos também que ele estende a classe RuntimeException, classe esta responsável por disparar exceções em tempo de execução. Além disso, o NullPointerException é o que em Java é chamado de “exceção verificada – unchecked exception.

Em “NULLPOINTEREXCEPTION, APRENDENDO A EVITAR”, vimos alguns erros que podem lançar esta exceção. Hoje trataremos da solução de alguns deles. Então, sem mais delongas vamos a elas.

SOLUÇÕES PARA O NULLPOINTEREXCEPTION

É importante que vocês saibam que o mesmo raciocínio empregado para resolver um NPE será empregado para resolver outras exceções. Trata-se do velho assunto sobre desenvolver uma mentalidade de programador.

Mas hoje faremos diferente, primeiro apresentarei o erro, e depois juntos, subiremos na pilha até encontrá-lo. Executaremos o código que já temos implementado. Abaixo o erro que foi exibido para nós no console.

Lendo de baixo para cima, temos que a exceção foi lançada na PrimeiraClasseJava, no método principal. Ao clicarmos sobre o destaque em azul, seremos direcionados para o ponto onde o erro foi gerado. Porém, tal como aprendemos em “PILHA OU FUNIL DE EXCEÇÃO”, ainda temos mais um nível para subirmos.

Então, ao ascender mais um nível podemos ver que ele aponta um erro na FuncaoAutenticaco. Ao clicarmos sobre o erro indicado somos redirecionados para a classe onde se encontra o método permitirAcesso.autenticar(), onde de fato “estourou” o null. Debugando o código, poderemos perceber que ao chamar o método, não passamos um valor a ele, deixando-o com nulo.

A correção é bem simples, basta passarmos algum valor para o método, no caso a variável “acesso”.

CORRIGINDO O 2º ERRO SIMULADO

Simulando mais um erro, veja o que o console exibe para nós.

Dessa vez ele nos diz apenas que o erro aconteceu na PrimeiraClasseJava no método main. Clicando no destaque somos redirecionados para linha de código onde adicionamos o aluno.

alunos.add(aluno1);

Bom, chegamos até este ponto e não existe mais nenhuma informação acerca do que pode ter lançado um NullPointerException. Para encontrar procederemos da seguinte forma, sabemos que implementamos uma lista – alunos. E é justamente onde adicionamos um item a lista que a IDE nos redireciona, então nada mais lógico do que procurarmos onde instanciamos a lista e ver se algo está acontecendo lá. E veja o que encontramos.

Ok, mas em um cenário com algumas dezenas de linha de código, percorrê-lo manualmente não é uma tarefa complexa. Mas e se tivéssemos centenas de linhas de código, esta tarefa se tornaria hercúlea. Entretanto, há uma solução, sabemos que se trata de uma lista.

PESQUISANDO NO ECLIPSE

Assim sendo, lá em alunos.add(aluno01), selecione o nome da lista (alunos), pressione as teclas CTRL+C e depois CTRL+F. Uma caixa de pesquisa será exibida.

Siga clicando em Find até encontrar, no caso, a lista inicializada com null, e então proceda com a correção.

List<Aluno> alunos = new ArrayList<Aluno>();

CORRIGINDO O 3º ERRO SIMULADO

Vamos treinar mais um pouco, irei um simular mais um erro para podermos analisar a mensagem que será exibida para nós no console.

E novamente o erro ocorreu na PrimeiraClasseJava no método main, porém, dessa vez o destaque aponta para outro local, clicaremos sobre ele para ver onde a IDE nos leva. Na linha 110 indicada no console temos a seguinte linha de código.

maps.get(StatusAluno.APROVADO).add(aluno);

Este caso não nos apresenta uma solução tão intuitiva como o anterior, porque o motivo da exceção pode ser a variável maps, pode ser que get(StatusAluno.Aprovado) não esteja trazendo o resultado esperado – lista, entre outros. Neste caso, o melhor caminho é “debugar” o código.

E não se preocupe, a nossa próxima série de tutorias será sobre debug, iremos aprender passo a passo como tirar o melhor proveito dessa técnica. Mas já adiantando, a palavra debug vem do inglês debugging, que em português significa depuração. Muito grosso modo, debug constitui um processo de encontrar defeitos seja em um software. O objetivo ao debugar um código é reduzir a zero os problemas encontrados.

DEBUGANDO O CÓDIGO

Dessa forma ao debugar o código, quando nos deparamos com a linha onde a exceção é lançada, poderemos explorar um pouco mais o que está acontecendo. Assim, posicionando o mouse sobre a variável maps, já poderemos ter uma ideia do que há de errado. Observe que há um objeto nulo.

Podemos também selecionar a expressão maps.get(StatusAluno.Aprovado) e pressionar as teclas CTRL+SHIFT+I, será então exibida uma tela como a mostrada abaixo, onde poderemos ver o objeto nulo.

É importante ressaltar que antes de checar toda a expressão primeiro verifiquei por meio do mesmo procedimento a variável maps. E só então parti para avaliar toda a expressão. Existe uma ordem, um passo a passo a ser seguido, do contrário continuaremos correndo às cegas.

Assim, vimos que a lista de aprovados que ele está tentando recuperar está nula, nenhuma lista está sendo passada.

O que precisamos fazer para corrigir este erro é instanciar a lista, ou seja, passar a lista que ele deverá recuperar.

maps.put(StatusAluno.APROVADO, new ArrayList<Aluno>());

EM POUCAS PALAVRAS

Acompanhando o que acabamos de fazer acredito que tenha ficado claro que o que fizemos se aplica a qualquer exceção lançada. Se sairmos buscando pelo erro de forma aleatória, não iremos conseguir descobrir o que fizemos de errado.

Por isso é importante o completo entendimento acerca de tudo o que já estudamos até aqui. É essencial a compreensão acerca dos conceitos e claro, a prática contínua, que visa solidificar o conhecimento teórico. O conhecimento é o que o permitirá conhecer seu código, e encontrar soluções baseadas nas melhores práticas.

Eu fico por aqui. Nos vemos no próximo tutorial onde aprenderemos a solucionar erros com a debug (depuração). Até lá.