Mensagem de erro de verificação nula como "é nulo" ou "foi nulo"
-
26-09-2019 - |
Pergunta
Ao fazer verificações nulas no código Java e você joga ilegalArgumentExceptions para valores nulos, que tipo de modelo de mensagem você usa?
Nós tendemos a usar algo assim
public User getUser(String username){
if (username == null){
throw new IllegalArgumentException("username is null");
}
// ...
}
O que é melhor: "NULL" ou "NULL" e por quê?
Para mim, "é nulo" parece mais natural.
Solução
Desde o Exception
é jogado devido a uma falha na verificação pré -condição, acho que, em vez de simplesmente declarar um fato, você deve declarar o requerimento Isso foi violado.
Isso é, em vez de dizer "username is null"
, dizer "username should not be null"
.
Ao usar bibliotecas para verificações de pré -condição
Como dica, você pode usar uma das muitas bibliotecas projetadas para facilitar as verificações pré -condicionais. Muitos códigos em goiaba usam com.google.common.base.Preconditions
Métodos estáticos simples a serem chamados no início de seus próprios métodos para verificar argumentos e estado corretos. Isso permite construções como
if (count <= 0) { throw new IllegalArgumentException("must be positive: " + count); }
para ser substituído pelo mais compacto
checkArgument(count > 0, "must be positive: %s", count);
Mais diretamente relevante aqui é que ele tem checkNotNull
, que permite que você simplesmente escreva:
checkNotNull(username, "username should not be null");
Observe o quão naturalmente o código acima diz, com a mensagem detalhada declarando explicitamente o requerimento Isso foi violado.
A alternativa de declarar fatos é mais estranha:
// Awkward!
checkArgument(count > 0, "is negative or zero: %s", count);
checkNotNull(username, "username is null");
Além disso, isso também é potencialmente menos útil, pois o cliente já pode estar ciente do fato, e a exceção não os ajuda a descobrir o que é real requisitos são.
Sobre IllegalArgumentException
vs. NullPointerException
Enquanto seu código original joga IllegalArgumentException
sobre null
argumentos, goiaba's Preconditions.checkNotNull
joga NullPointerException
em vez de.
Isso está de acordo com a diretriz definida pela API:
NullPointerException
: Os aplicativos devem lançar instâncias desta classe para indicar outros usos ilegais donull
objeto.
Além disso, aqui está uma citação de Java 2ª edição eficaz: Item 60: favorece o uso de exceções padrão:
Indiscutivelmente, todas as invocações de método errôneas se resumem a um argumento ilegal ou estado ilegal, mas outras exceções são usadas padrão para Certos tipos de argumentos e estados ilegais. Se um chamador passar
null
Em algum parâmetro para o qual os valores nulos são proibidos, a convenção determina queNullPointerException
ser jogado ao invés deIllegalArgumentException
.
Outras dicas
é nulo, já que o argumento ainda é nulo ..
No entanto, por que não simplesmente jogar um NullPointerException sem uma mensagem?
Eu sugeriria dizer
if (userName == null) {
throw new IllegalArgumentException("username == null");
}
Como isso é tão fatal que um programador deve olhar para ele de qualquer maneira. Referir o snippet de código ofensivo na mensagem de exceção é a coisa mais concisa que posso imaginar.
Eu estaria inclinado a escrever isso:
public User getUser(String username) {
if (username.length() == 0) {
throw new IllegalArgumentException("username is empty");
}
// ...
}
Isso mata dois pássaros com uma pedra. Primeiro, ele detecta o caso em que o nome de usuário é uma string vazia, que (por uma questão de argumento), suponho que seja um erro. Segundo, se o parâmetro for null
tentando despachar o length
Chamada dará um NullPointerException
.
Para o registro, o esperado Exceção a ser lançada para um inesperado null
é NullPointerException
. Se o seu principal motivo para não usá -lo é que o NPE normalmente não tem uma mensagem, codifique -o assim:
public User getUser(String username){
if (username == null){
throw new NullPointerException("username is null");
}
if (username.length() == 0) {
throw new IllegalArgumentException("username is empty");
}
// ...
}
Por que usar os NPEs estão aqui? Porque o NPE é quase sempre indica um tipo diferente de problema para outros tipos de erro de validação de argumento; Por exemplo, um campo ou célula de matriz que não foi inicializada ou um valor "opcional" que não está sendo tratado corretamente.
Finalmente para a pergunta:
O que é melhor :
"is null"
ou"was null"
, e porque?
Isso é uma questão de opinião, mas eu escreveria "is null"
.
- Porque a mensagem está relatando o estado quando a exceção foi lançada.
- Porque é convencional fazê -lo dessa maneira.