Não há problema em colocar Nullpointerexcepção programaticamente?

Quando existe uma condição pós-condição, que o valor de retorno de um método não deve ser nulo, o que pode ser feito?

Eu poderia fazer

assert returnValue != null : "Not acceptable null value";
Mas as afirmações podem ser desligadas!

então está tudo bem para fazer

if(returnValue==null)
      {
           throw new NullPointerException("return value is null at method AAA");
      }

?

ou é melhor usar uma excepção definida pelo utilizador (como NullReturnValueException ) para tal condição?

Author: Cœur, 2010-07-24

19 answers

Não vejo qualquer problema em lançar um NPE o mais cedo possível antes que o JVM o faça por si - em particular para argumentos nulos. Parece haver algum debate sobre isso, mas há muitos exemplos nas bibliotecas Java SE que fazem exatamente isso. Não consigo ver por que NPE deve ser santo no aspecto de que você não é capaz de lançá-lo você mesmo.

No entanto, estou a divagar. Esta pergunta é sobre algo diferente. Está a falar de uma pós-condição que afirma que o valor de retorno não deve ser nulo. Certamente nulo neste caso significaria que você tem um bug dentro do próprio método? Como é que documentarias isto? "Este método lança uma ideia de ponto null se o valor de retorno inesperadamente for nulo"? Sem explicar como isto pôde acontecer? Não, eu usaria uma afirmação aqui. Exceções devem ser usadas para erros que podem acontecer-não para cobrir coisas que podem acontecer se houver algo errado dentro do método, porque isso não ajuda qualquer.
 38
Author: waxwing, 2010-07-24 23:10:16
Recomendo que nunca atires sozinho. A principal razão para não fazer isso, como Thorbjørn Ravn Andersen diz em um comentário abaixo, é que você não quer misturar 'NPEs reais, ruins' com NPEs jogados intencionalmente.

Então, até estar confiante de que é capaz de reconhecer o NPE 'válido', eu recomendaria usar {[[1]} quando quiser dizer ao seu utilizador da API que null não é um valor de argumento válido. O comportamento do seu método quando o parâmetro nulo ilegal for aprovado deverá seja documentado.

Outra opção (mais moderna imho) é usar @NotNull anotação perto do argumento. Aqui está um artigo sobre a utilização da anotação @NotNull .

Como mencionei anteriormente, também pode haver casos, quando atirar NPE não será confuso para você ou para seus companheiros de equipe: a causa NPE deve ser clara e reconhecível.

Por exemplo, se usar alguma biblioteca com módulo pré-requisitos, como Guava, então acho que usar métodos semelhantes a checkNotNull() é uma forma preferível para lidar com nulls ilegais.

checkNotNull(arg, msg) lança NPE, mas a partir do stacktrace é bastante claro, que foi produzido por Preconditions.checkNotNull() e, portanto, não é um bug desconhecido, mas um comportamento esperado.

 59
Author: Roman, 2013-02-18 11:37:27

Dado que NullPointerException é a forma idiomática de comunicar um valor nulo inesperado em Java, eu recomendaria que você lançasse um padrão NullPointerException e não um homegrown. Também tenha em mente que o princípio da menor surpresa sugeriria que você não inventa seu próprio tipo de exceção para um caso onde um tipo de exceção do sistema existe.

As afirmações são boas para depuração, mas não Boas se você tiver que lidar com certas condições de modo que não é realmente uma boa maneira de lidar com o erro condicao.

 27
Author: Timo Geusch, 2010-07-23 21:49:57

O problema com {[[0]} é que ocorre quando você se esquece para verificar se algo é nulo ou dar o argumento errado que é nulo, e não deve.

Pela minha experiência, programadores Java aprendem muito rapidamente que esta exceção é causada pelo bug em código, então lançá-lo manualmente será extremamente confuso para a maioria deles. IllegalArgumentException é melhor idéia quando você passa argumento inaceitável (como null, onde algo não deve ser null).

Isto despoleta também outro heurístico. NPE = alguém cometeu um erro no código aqui, IllegalArgumentException = o objecto dado ao método é inválido. Por outro lado, o javadoc diz:

As aplicações devem lançar instâncias desta classe para indicar
outras utilizações ilegais do objecto null.

Então atirar NPE seria legal, mas não é a prática comum, então eu recomendaria IllegalArgumentException.
 12
Author: Danubian Sailor, 2013-03-22 16:04:50
Certamente não há uma lei universal contra a ideia de colocar um ponto final, mas é difícil responder se você realmente deve dar um exemplo tão abstrato. O que você não quer fazer é colocar as pessoas na cadeia na posição de tentar pegar o ponto final. Código como este (exemplo real, eu juro):
catch (NullPointerException npe) {
  if (npe.getMessage().equals("Null return value from getProdByCode") {
    drawToUser("Unable to find a product for the product type code you entered");
  } 
}
É um indicador seguro de que estás a fazer algo de errado. Então, se o valor de retorno nulo é um indicador de algum estado do sistema que você realmente é capaz de comunicar, usar uma exceção que comunica esse estado. Não há muitos casos em que eu possa pensar em que faz sentido anular uma referência apenas a chuck um ponteiro de null. Normalmente, a próxima linha de código teria despejado o ponteiro de NULL (ou algo mais informativo) de qualquer maneira!
 7
Author: Affe, 2010-07-23 22:12:23

Eu consideraria que o uso de NullPointerException ok, Se você se lembrar da descrição. É com isso que a pessoa que investiga tem trabalho (números de linha podem mudar). Lembre-se também de documentar que os seus métodos lançam exceções de ponteiros nulos em casos especiais.

Se verificares os parâmetros do teu método logo no início, a throw new IllegalArgumentException("foo==null") também é aceitável para mim.

 5
Author: Thorbjørn Ravn Andersen, 2010-07-23 23:00:18

O JavaDoc para NullPointerException diz:

Atirado quando uma aplicação tenta usar o valor nulo num caso em que um objecto é necessario. Estes incluem:

* Calling the instance method of a null object.
* Accessing or modifying the field of a null object.
* Taking the length of null as if it were an array.
* Accessing or modifying the slots of null as if it were an array.
* Throwing null as if it were a Throwable value. 

As aplicações devem lançar exemplos de esta classe para indicar outros ilegais utilização do objecto nulo.

Considero violar a condição pós-condição uma acção ilegal. No entanto, acho que a exceção que você usa não importa muito, porque estamos falando de um caminho de código isso deve ser (e espero que seja) inacessível, e, portanto, você não terá manipulação de erros específicos para essa exceção, e, portanto, o único efeito desse nome é uma formulação diferente de alguma entrada em um arquivo de log ninguém é provável ver.

Se, em contraste, você pensa que a condição de post é susceptível de ser violada, pode ser uma boa ideia incluir mais informações de depuração, tais como os argumentos com os quais o método foi invocado.

 3
Author: meriton, 2010-07-23 22:10:57

Se descrever um contrato de método em que o valor de retorno não pode ser {[[0]}, então é melhor certificar-se de que não devolve null. Mas isto não é uma boa ideia. Se o valor de retorno é null, em seguida, claramente o autor da chamada tem dado maus argumentos (IllegalArgumentException), você não está em um estado válido (IllegalStateException), ou algum outro muito mais significativo condição excepcional ocorreu diferente NullPointerException (que normalmente indica um erro de programação).

 3
Author: Tim Bender, 2010-07-24 06:32:21

Http://pmd.sourceforge.net/pmd-5.0.1/rules/java/strictexception.html
"Evitem atirar pedras de ponto. Estes são confusos porque a maioria das pessoas vai assumir que a máquina virtual jogou-o. Considere, em vez disso, a utilização de uma Excepçãolegalargumentosa; esta será claramente vista como uma excepção iniciada pelo programador."

 3
Author: Gab, 2017-06-29 11:56:42

Um livro que eu chamei de O'Reilly's Java em poucas palavras {[3] } que é escrito por um especialista lista esta definição para a percepção de ponto null:

Sinaliza uma tentativa de aceder a um campo ou invocar um método de um objecto nulo.

Uma vez que devolver null não é nenhuma dessas coisas, acho que seria mais apropriado escrever a sua própria exceção.
 1
Author: Rafe Kettler, 2010-07-23 22:08:50
Muitas vezes é uma boa ideia lançar o NPE antes que a lógica se torne tão profunda que o programador de chamadas tenha dificuldade em descobrir o que era nulo. os métodos addListener() são um bom exemplo. Não obstante, existem muitos métodos no JDK que fazem exatamente isso.
 1
Author: user207421, 2017-07-19 10:49:29
Nunca se deve lançar manualmente uma cápsula de localização completa. A rotina de chamada não saberia se a real ou manual localização completa sem verificar a descrição. Neste caso, parece que você gostaria de rolar sua própria exceção que corresponde ao problema mais perto, de modo que o método de chamada pode recuperar corretamente frm esta exceção. Talvez uma excepção pós-con-dicção seja genérica o suficiente para muitas circunstâncias.
 0
Author: Jerod Houghtelling, 2010-07-23 23:21:39

No Java-verse null é sempre um valor válido quando se espera um objecto. É melhor evitares essas condições impossíveis. Se você realmente não pode suportar um null então você terá que refazer o seu método para que você possa retornar um primitivo.

 0
Author: CurtainDog, 2010-07-24 07:47:48
Como Joshua Bloch disse: "Null sucks!":) sempre que há null é o meu rosto, eu tento usar o opcional que a goiaba fornece. As vantagens são numerosas para mim.
 0
Author: Eugene, 2013-02-18 11:40:53
Absolutamente sim. Até o JDK7 resolve isto. Ver objectos # requireNonNull
void doWith(final Object mustBeNotNull) {

    /*
    // bush style
    if (mustBeNotNull == null) {
        throw new IllegalArgumentException("mustBeNotNull must not be null");
    }
    */

    /*
    // obama style
    if (mustBeNotNull == null) {
        throw new NullPointerException("mustBeNotNull must not be null");
    }
    */

    // kangnam style
    Objects.requireNonNull(mustBeNotNull, "mustBeNotNull must not be null");

    assert mustBeNotNull != null;
}
 0
Author: Jin Kwon, 2013-03-05 01:04:25

Quando existe uma condição pós-condição, que o valor de retorno de um método não deve ser nulo, o que pode ser feito ?

Uma condição pós-condição significa que o método em questão tem um bug se a condição não for cumprida. A forma de expressar isto em código é usando um assert na condição de pós-condição. Atirar diretamente uma exceção, como um NullPointerException ou um IllegalStateException, seria um pouco enganador, e, portanto, equivocado.

Não há problema em lançar a pista de aterragem. programaticamente?

O Doc da API Java para o NPE diz sim, mas, a julgar pelos votos dados nesta página, uma maioria de desenvolvedores 3:1 diz não. Então eu diria que depende das convenções no seu grupo de trabalho.

O API doc primeiro lista os casos em que o JVM levanta um NPE porque o código tenta invocar uma operação numa referência nula que requer um objecto de algum tipo (como chamar um método ou aceder a um campo), e null não é um objecto. Em seguida, afirma: ([19])

As aplicações devem lançar instâncias desta classe para indicar outras utilizações ilegais do objecto null.

Curiosamente, {[3] } é chamado de" objeto " aqui, o que não é. O que me lembra que o próprio nome NullPointerException é bizarro para uma linguagem que não tem ponteiros. (Que provavelmente deveria ter sido NullReferenceException como na biblioteca de classe Microsoft. NET.) Então, devemos dispensar o médico da API nesta contagem? Não me parece. A biblioteca de classes usa o NPE como descrito nos documentos, por exemplo, em java.nio.channels:

Salvo indicação em contrário, passar um argumento null para um construtor ou método em qualquer classe ou interface deste pacote fará com que um NullPointerException seja lançado.

Este não é um NPE gerado pela JVM, mas um NPE codificado com uma mensagem de erro anexada indicando que argumento era null (Como "in" is null!). (O código pode ser visto fazendo javap -c -p java.nio.channels.Channels | more, procurando por private static void checkNotNull.) E há muitas classes que usam NPEs desta forma, essencialmente como um caso especial de IllegalArgumentException.

Então, depois de investigar um pouco e pensar sobre isso, eu acho que este é um bom uso do NPE, e, portanto, eu concordo com a API doc e uma minoria de desenvolvedores Java (como por votos nesta página) que têm direito, e o direito a usar o NPE em seu próprio código, da mesma forma a classe Java a biblioteca não faz, que é fornecer uma mensagem de erro, o que é manifestamente ausente da JVM gerado NPEs, que é por isso que não existe nenhum problema em dizer a dois tipo NPE à parte.

Para abordar o ponto menor que o NPE será jogado de qualquer forma mais adiante na estrada: pode muito bem fazer sentido apanhar erros cedo em vez de permitir que o JVM continue com o programa, possivelmente envolvendo disco ou rede I/O (e atrasos), e gerando um traço desnecessariamente grande pilha.

 0
Author: Lumi, 2014-02-03 13:21:56
Sim, está tudo bem, mas eu diria que é uma decisão melhor deixar acontecer.

O problema com programadores Java e null é que as pessoas vêm de um fundo C / C++, onde NULL significa algo muito diferente. Em C / C++ a dereferenciação de um ponteiro nulo (ou selvagem) é um problema sério que pode causar problemas de memória estranhos ou interromper o seu programa (obviamente não é desejável). Se você pode sair da maneira de pensar C/C++ e você percebe que você tem esta camada extra, a JVM, que lida com esta condição para você, você começa a pensar em NULL um pouco diferente.

Em C++ temos referências, por exemplo, que nunca podem ser atribuídas nulas. Em Java, não há referências, mas os parâmetros de objetos Java se comportam mais como ponteiros c++. Mas há um monte de situações em Java em que um método implicitamente deve não receber um valor nulo para um parâmetro! Então, o que fazemos?

O problema de tratar null em Java como você faz em C++ é que isto resulta em verificações nulas em todo o lado, ao passo que em C++ Você estaria simplesmente declarando um método para tomar uma referência, que explicitamente afirma que ele não aceita NULL. Muito em breve, cada método tem que ter uma verificação de sanidade nele apenas para afirmar a condição do programa nesse ponto, criando uma confusão.

É um estado de espírito muito melhor trabalhar sob a suposição de que o contrato padrão de um método é que null é inválido para um valor de parâmetro.

Porquê? Bem, vamos ver. no que acontece quando tal método recebe null como um valor de parâmetro. a) Talvez esteja tudo bem porque não dereferência o valor como parte de seu comportamento. Neste caso, nada acontece. b) O valor é dizimado. Neste caso, o comportamento da JVM é exatamente o que desejamos: uma exceção é lançada indicando que o Contrato do método foi violado devido a um valor de parâmetro ser nulo, e inclui um traço de pilha que nos leva até a linha no método em que o valor do parâmetro foi violado. o valor é utilizado desta forma. As pessoas discutem com o NPE porque acham que quando vemos o NPE nos registos, significa "alguém fez asneira". Mas vamos pensar nisto por um segundo. Qual é realmente a diferença no NPE como um indicador de erro em oposição ao comportamento esperado? Eu argumentaria a grande diferença (e vantagem) de usar o NPE como comportamento esperado é que ele aponta não para o método em que ocorreu, mas para o chamador por violar o Contrato do método. Isto é muito. mais informações úteis. Se fôssemos simplesmente verificar nula e lançar uma exceção diferente, poderíamos estar sob a falsa impressão de que o comportamento observado é um erro esperado, quando realmente o chamador está violando o Contrato do método. Parabéns, você corretamente previsto como você o chamador pode estragar chamar o método - no entanto, tudo que você tem feito é led-se extraviaram, como o que a real causa da exceção é - ou na melhor das hipóteses, você está usando duas diferentes classes de exceção para indicar a mesma coisa e sujar massivamente o código com lixo desnecessário entretanto. Por isso, no fundo, as pessoas consideram o NPE tabu. Literalmente as pessoas não vão permitir que ele seja jogado porque há algum senso de vergonha que vai com ele-como se você não é inteligente o suficiente porque você não conseguiu adivinhar onde um valor seria nulo. Tenho novidades para vocês, estão a escrever um código mais inútil para fazer a mesma coisa.

Alguns exemplos:

public void foo(Object o) {
  if (o == null) {
    throw new IGotchaException("HA! You're an IDIOT! I knew it!!");
  }
  o.bar();
}

public void foo(Object o) {
  o.bar();
}
Política diferente. Funcionalmente, nem por isso.
public void foo(int a, long b, double c, Object o) {
  if (o == null) {
    throw new IllegalArgumentException("Oh. Uh. Well, you've passed me null here. I... I'm not sure where to go from here because this object is kind of required for this function to do what it's supposed to do. Soooo... wouldja mind reworking your code a little bit so as to not pass null to this function as a parameter?! That'd be great thanks. Oh by the way, it's cause we deference o 40 lines below here");
  }
  // ...
  o.doSomethingWithA(a);
}

public void foo(int a, long b, double c, Object o) {
  // ...
  o.doSomethingWithA(a);
  // NullPointerException, line 40, e.g. it wasn't OK to pass null for o you lunkhead
}
Talvez poupe alguns ciclos de CPU à custa de muitos códigos irritantes. No entanto, fazemos menos comparações no segundo caso.
public void foo(Object a, Object b, Object c, Object d) {
  if (a == null) throw IllegalArgumentException("jackass");
  if (b == null) throw IllegalArgumentException("jackass");
  if (c == null) throw IllegalArgumentException("jackass");
  // But d is totally OK!
  // ...
  c.setSomeValueThatMayBeNull(d);
}

public void foo(Object a, Object b, Object c, Object d) {
  // ...
  c.setSomeValueThatMayBeNull(d);
  // Throws null pointer exception if c is null, but not if d is null. Which is basically the same as above
}
O contrato está implícito na declaração e não num caso de excepção no início do método. Não oferece outra desvantagem.
public void foo(Object o) {
  if (o == null) {
    doTheBoogie();
  } else {
    doTheRobot();
  }
}

^ mau

public void foo(Object o, int b) {
  Bar value = o.findSomethingWhichMayExist(b);
  if (value == null)
    return;
  value.doSomething();
}

^ Usando o valor de retorno nulo para indicar a ausência de um valor. BEM.

Outra razão pela qual as pessoas têm problemas com o NPE é porque não sabem lidar com exceções. A NPE nunca deve ser uma exibicionista. O comportamento apropriado é pegar a percepção de Runtimeexcepção, presumivelmente em um nível muito mais alto (ou mais baixo, dependendo de como você vê) na pilha de chamadas que prende-lo e relatá-lo antes de "main". Isto é, assumindo que você está desenvolvendo o tipo de programa que precisa ser mais resistente e não pode simplesmente bater quando um NPE acontece.

Fundo linha: nunca espere que seja uma coisa válida estar passando em valores nulos para os parâmetros do método. E definitivamente não crie um contrato para um método que aceita explicitamente nula e o trate como um valor válido. Mas, permitir excepções de ponteiro nulo para acontecer, e deixar o código falhar, ou não falhar quando não importa, naturalmente.

 0
Author: Erich, 2017-06-29 11:08:19

Eu concordo com a afirmação nas respostas anteriores, que o NPE é bug em código e não deve ser jogado, mas o desenvolvedor deve corrigir null inesperado. No entanto, este estado pode ser evitado a maior parte do tempo por testes.

A pergunta foi feita antes de 7 anos, mas agora temos opcional em java 8 e este recurso permite prevenir NPE.

A última solução, que tenho em mente, é que você deve verificar o objeto em null e se ele for igual, então jogue sua própria exceção com a descrição do que aconteceu.

 0
Author: Peter S., 2017-10-04 19:02:13

Abrir essa excepção não é uma boa prática em algum caso e eu me pergunto por que quando você já pegá-lo com a declaração if?

If (returnValue= = null)

 -1
Author: Truong Ha, 2010-07-24 01:53:47