Por que meu NullPointerException não ser pego no meu bloco catch?
-
13-09-2019 - |
Pergunta
Eu tenho um segmento em que eu pegar todos os erros em um grande e abrangente bloco catch. Eu faço isso para que eu possa relatar qualquer erro, não apenas as esperadas, em meu aplicativo. Meus olhares Execut�eis como este:
public final void run()
{
try
{
System.out.println("Do things"); /* [1] */
doUnsafeThings();
}
catch (Throwable t)
{
System.out.println("Catch"); /* [2] */
recover();
}
finally
{
System.out.println("Finally"); /* [3] */
}
}
Espero que o NPE a ser capturado pelo bloco captura Throwable. Em vez disso, a saída em [2] não é impresso, e nem é [3]. A saída em [1] é impresso.
O que eu recebo no console, é o seguinte:
Uncaught exception java/lang/NullPointerException.
O que diabos está acontecendo aqui?
Para os registros do tribunal, eu estou usando J2ME, e este está em execução no emulador WTK v2.5.2 do Sol.
Estou tentado a colocá-lo para baixo a JVM implementação dodginess mas não posso deixar de sentir que eu só estou faltando alguma coisa.
Para esclarecer para que não restem dúvidas (Desde que o código de exemplo é obviamente alterada do meu código de produção)
- Não há nada fora do try / catch / finally bloco no método de execução.
- Há um System.out.println no início de cada um desses blocos -. O que se segue essas declarações de console não deve importar
Solução
A resposta Acontece que eu sou um idiota. Eu explicar o que deu errado, mas vamos chamá-lo de "um daqueles erros".
Eu tinha esquecido momentaneamente que o fio que corria o executável foi uma classe Thread personalizado (Para contornar alguns bugs da Nokia). É chamado run()
repetidamente entre chamadas para um método canWait()
.
O método canWait foi responsável pelo fracasso, e correr não estava falhando em tudo. Para cobri-lo fora, eu tenho consola-cegueira e completamente, mas acidentalmente citado erroneamente a sequência de acontecimentos na minha pergunta.
Outras dicas
Parece que você vai precisar de alguma tentativa e erro. Posso sugerir:
try {
doEvilStuff();
} catch (NullPointerException ex) {
System.out.println("NPE encountered in body");
} catch (Throwable ex) {
System.out.println("Regular Throwable: " + ex.getMessage());
} finally {
etc...
}
Por ter uma captura explícita para NullPointerException, deveria ser óbvio, se a exceção é de dentro do bloco try ou catch / finally bloco.
Ok, isso é um palpite ... mas seria explicar as coisas.
Obviamente seu código não é realmente que - por isso o meu palpite é que a sua captura (ou finalmente) bloco é tanto fazer algo antes que registra nada, ou ele usa um registrador diferente do bloco try. De qualquer maneira, eu suspeito que seja a captura ou bloco finally é lançar a exceção.
Eu não suponha que você tenha um rastreamento de pilha ...
EDIT: Ok, se é apenas System.out.println
, é algo no argumento de que poderia ir Bang? Por exemplo:
catch (Throwable t) {
// Will go bang if t.getCause() returns null
System.out.println(t.getCause().getMessage());
}
Se é System.out.println("Constant")
apenas simples, então é muito estranho.
Você sabe (por exemplo, a partir de linhas de registo dentro do bloco try) quanto o bloco try está realmente ficando?
Quando eu olhei para o seu código parece que recuperar () é lançar uma exceção, então o conselho dado por Jon seria excelente a seguir.
Se você nos deu um rastreamento de pilha que você pode obter uma melhor ajuda.
Quando tento capturar exceções eu faço algo como isto:
try {
doSomethingBad();
} catch(Exception e) {
try {
LogException(...);
} catch(Exception e) {}
} finally {
}
Eu não gosto de exceções ninho, mas eu não gosto de minha captura bloco lançar exceções.
Como você menciona que você está usando um Runnable
- faz isso por qualquer meio chance de que você está usando vários segmentos também? Se o método doUnsafeThings()
gera internamente um segmento diferente de novo e que produz a exceção, você não pode obtê-lo no segmento de seu bloco catch é.
Consulte http: //java.sun .com / J2SE / 1.5.0 / docs / api / java / lang / Thread.UncaughtExceptionHandler.html
Em geral, é uma má prática para pegar NullPointerException.
programadores tipicamente pegar NullPointerException sob três condições:
The program contains a null pointer dereference. Catching the resulting exception was easier than fixing the underlying problem.
The program explicitly throws a NullPointerException to signal an error condition.
The code is part of a test harness that supplies unexpected input to the classes under test.
Destes três circunstâncias, apenas o último é aceitável. seguindo este link:
É possível que o segmento está sendo morto por algum outro código? Em um general bloco finally sempre executa a menos que o segmento está terminada anormalmente, quer por System.exit () ou algo similar.
-
Tem certeza de que você está procurando no lugar certo no código? Ou seja, é o doUnsafeThings () bloquear você está protegendo em do rastreamento de pilha?
-
Talvez haja um problema com o seu método de construção, e você está depurando uma versão antiga do código?
apenas adicionar um pouco de logging nos doUnsafeThings (); para ver se esse método é fazer o que você espera (por exemplo, colocar um try catch finalmente e log algo)