Estou com uma dúvida sobre exceções em java, estou lendo o livro Effective - Java, nele o autor fala sobre exceções e diz que nunca, ou quase nunca, devemos tratar uma exceção não verificada, pois sempre se trata de uma situação de erro que não há possibilidade de tratamento ou recuperação, porém colocando a seguinte situação, um sistema simples uma agenda com parte gráfica desenvolvida em swing digamos que exista um método
public void cadastrarUsuario(Usuario usuario) {
...
}
caso esse método seja invocado com o usuário igual a null irá lançar um exceção não verificada NullPointerException, até aqui ok, essa exceção será capturada pela JVM e no caso de estarmos executando em um console ou dentro do eclipse irá aparecer a exceção lançada no console, porém se tivermos excecutando um .jar, empacotamos a aplicação para destribuí-la e nosso cliente esta executando um .jar, onde essa exceção será mostrada?, o usuário pode ficar clicando infinitas vezes no botão “Adicionar Usuário” que nada irá acontecer e nenhum erro irá aparecer. Essa pode ser uma situação simples, que alguns podem dizer, “Verifica se o objeto está null antes e se estiver mostra um mensagem para o usuário”, mas podem existir situações mais complexas, e ai me pergunto não verifico uma exceção não verificada e posso deixar o usuário do sistema sem resposta, nem ao menos de erro.
Ainda podemos pensar, crie uma classe de exceção própria que estenda de Exception ou Runtime ou até mesmo nesse exemplo NullPointerException, que grave um log ou que mostre a exceção de alguma forma, mais ai vamos quebrar outra boa prática que contém no livro que é, reutilize as classes de exceção que já existam e teríamos que ter várias classes de exceção que servem para a mesma coisa que suas superclasses, apenas exibem ou geram log das mensagens de erro.
NullPointerException nos lembra que não estamos testando corretamente a aplicação se precisamos ficar tendo que tratar dessas coisas. A menos que seja um jar de terceiros com algum bug inconveniente.
Que permite que você defina um listener que irá capturar todas as exceções de Runtime que não foram capturadas por nenhum catch. É esse cara que, por padrão, exibe a mensagem de erro no console. Através dele, você pode exibir uma mensagem de erro padrão (mesmo que um .jar externo tenha disparado a exception) ou simplesmente logar o problema em algum arquivo de texto.
As threads também tem o método não estático chamado setUncaughtExceptionHandler, para caso você queira definir um comportamento específico de tratamento de exceptions não pegas para uma thread individual.
Excecoes sao para casos excepcionais Uma das coisas mais importantes que voce tem que fazer quando escreve a UI é validar os dados que o usuario insere no sistema. Se o usuario preencher um campo de forma incorreta ou nao preencher um campo obrigatorio, o sistema nao deve nem comecar a executar a regra de negocio (e assim deixar estourar um NullPointerException). Isso é muito importante em qualquer sistema.
Para situacoes de erros inesperados (servidor fora do ar, bug no codigo, erros de I/O, etc), o sistema deve ter um mecanismo que informe o usuario que o erro aconteceu e tente deixar o sistema num estado mais consistente. A dica do ViniGodoy é excelente para sistemas Swing e a do jakefrog é excelente para sistemas Java EE (ja que o servidor de aplicacoes geralmente tem um sistema de logging de excecoes nao tratadas pela aplicacao)
Achei muito interessante este método Thread.setDefaultUncaughtExceptionHandler porque sempre existirão exceções não verificadas que podem ser lançadas em backgroud sem que o usuário veja que o processo esta com problema, era isso mesmo que eu procurava.
Claro que devemos evitar esse tipo de problema, mais se temos uma exceção não verificada, não temos que tentar pegá-la em um bloco try catch, porque possivelmente não vamos conseguir recuperar o sistema após a exceção, e quando essa exceção acontecer alguma mensagem deve ser direcionada para o usuário, ou ao menos para um arquivo de log.