Por que devemos escrever classs de exceção personalizadas em Java

Qual é o propósito de escrever classs de exceção personalizadas quando a maioria delas é o mesmo. Por exemplo, NullPointerException :

class NullPointerException extends RuntimeException { private static final long serialVersionUID = 5162710183389028792L; public NullPointerException() { super(); } public NullPointerException(String s) { super(s); } } 

Este é o modelo básico para a maioria das classs de exceção que vi e criei.

Um propósito que eu posso pensar é no tratamento dessas exceções.Mas então não pode ser baseado em mensagem de exceção ?. Principalmente escrevemos código de manipulação única para cada tipo de exceção. Eu sei que existem ‘exceções’ para isso.

Mas há algo mais nisso? Isso não está se repetindo onde apenas o nome da class muda?

Também há alguma class de Exceção do JDK que tenha algum código além disso?

Eu posso pensar em várias razões:

  • Ter várias classs de exceção permite que o programador seja específico em suas cláusulas catch e capture apenas as exceções com as quais se importa e saiba o que fazer.
  • Uma class de exceção pode transportar informações sobre o erro que causou a exceção. Por exemplo, ArrayIndexOutOfBoundsException carrega o índice de matriz ofensivo e as exceções SQL tendem a conter códigos e mensagens de erro específicos do database.
  • Especificações de exceção – que listam classs de exceção – podem ser usadas para verificar a correção em tempo de compilation.

Bem, simplesmente, se você não precisa de uma class de exceção especial, você não deve fazer uma. Se você fizer, então você faz um. Não há mágica para isso realmente.

Se você está fazendo uma biblioteca, então você deve, é claro, pensar do ponto de vista dos desenvolvedores usando a biblioteca (mesmo que seja apenas você): sua biblioteca lança exceções por razões específicas e poderia o usuário da biblioteca possivelmente querer pegar especificamente estes, porque eles podem realisticamente fazer algo sobre isso (apenas o registro não é razão suficiente, IMO).

Exemplo com classs de exceção padrão: O chamador de um método pode querer converter IndexOutOfBoundsException em valor de retorno null , enquanto deixa outras exceções se propagar normalmente.

Se você quiser que sua exceção personalizada seja manipulada de formas padrão, estenda a class de exceção existente correta, como IOException . Você pode capturar sua exceção IO específica quando quiser fazer algo específico, mas também deixá-la ser tratada como qualquer outra IOException quando não precisar de tratamento especial (não pode fazer nada útil para recuperar).

Se você tiver uma exceção totalmente personalizada que nunca deve ser capturada por uma captura de superclass, que sempre deve ter um bloco catch específico, estenda Exception diretamente.

Eu acho que é muito raro precisar estender RuntimeException , porque se for uma exceção que deve ser capturada, deve ser a subclass Exception , e se é para finalizar o programa ou apenas gerar saída de log, ele deve ser coberto por implementações RuntimeException padrão com string de mensagem personalizada.

  1. Teremos a liberdade de adicionar mais alguns methods em nossa class Exception, o que ajuda o cliente como rootCauseOfException (), description (), solution (), suggestions () etc. Pode consultar o link abaixo:
    https://stackoverflow.com/a/22698673

  2. Se o seu projeto tiver módulos interdependentes, você poderá manter a hierarquia de exceções também na mesma hierarquia de dependencies, de modo que, se você capturar uma única Exceção na camada base, todas as exceções dos módulos interdependentes serão capturadas.

  3. Você também pode mascarar alguns dados confidenciais como ip, porta etc antes de enviar para o lado do cliente. Se as exceções personalizadas não forem usadas, alguns dados confidenciais podem vazar para o slient.

  4. Você pode fornecer sua própria mensagem de exceção, que pode ser facilmente compreendida pelo cliente, em vez da mensagem de exceção do java, às vezes, que pode ser difícil de entender.

É basicamente para lidar com diferentes exceções de maneiras diferentes. Digamos que você queira fazer alguma operação diferente no ArrayIndexOutOfBoundsException do que um NumberFormatException.

ou mais claramente

 }catch (ArrayIndexOutOfBoundsException ex){ //operation 1 }catch (NumberFormatException ex){ //operation 2 } 

O objective principal seria identificar os erros personalizados / específicos do aplicativo. Você também pode fornecer alguns methods adicionais lá. Por exemplo, temos exceções personalizadas que retornam mensagens personalizadas e também extrai causa e localização do rastreamento de pilha.

Você precisa ter seu código de cliente saber qual exceção exata acontece por qual parte do código. então você precisa deixar a exceção semântica e distinguida de outro bloco de código.

Como fazer isso:

  1. Definir nova class de exceção, então o nome da class informa o que acontece
  2. Defina uma class de exceção unificada / genérica que envolva code , message ou outras informações. o code pode dizer o que acontece.

Para resumir, faça algo deixar sua exceção ter algum significado / semântica, e deixe seu cliente saber exatamente o que acontece.