Quando apanhar café.idioma.Erro?
16 answers
Se está a escrever o código framework-ish (a carregar classes de terceiros), pode ser sensato apanhar erros de ligação (não foi encontrado nenhum def de classe, ligação insatisfeita, mudança de classe incompatível). Também vi um código de terceira-festa estúpido a lançar sub-séries de erros, por isso vais ter de lidar com estes também.
A propósito, não sei se é possível recuperar-se do passado.Geralmente você deve sempre pegar {[[1]} e escrevê-lo em um registro ou mostrá-lo ao usuário. Eu trabalho em apoio e vejo diariamente que os programadores não podem dizer o que aconteceu em um programa.
Se você tem um tópico do daemon então você deve evitar que ele seja terminado. Em outros casos, sua aplicação funcionará corretamente.
Só se deve apanhar java.lang.Error
ao nível mais alto.
Se olhar para a lista de erros verá que a maioria pode ser tratada. Por exemplo a ZipError
ocorre ao ler ficheiros zip corrompidos.
Os erros mais comuns são OutOfMemoryError
e NoClassDefFoundError
, que são ambos na maioria dos casos problemas de tempo de execução.
Por exemplo:
int length = Integer.parseInt(xyz);
byte[] buffer = new byte[length];
Pode produzir um OutOfMemoryError
mas é um problema de tempo de execução e não há razão para terminar o seu programa.
NoClassDefFoundError
ocorrer principalmente se uma biblioteca não estiver presente ou se você trabalhar com outra versão Java. Se é uma parte opcional do seu programa, então você não deve terminar o seu programa.
Eu posso dar muitos mais exemplos de por que é uma boa idéia pegar Throwable
no nível superior e produzir uma mensagem de erro útil.
try {
while (shouldRun()) {
doSomething();
}
}
catch (Throwable t) {
log(t);
stop();
System.exit(1);
}
Mesmo, em alguns casos, você gostaria de lidar com diferentes Erros de forma diferente, por exemplo, no OutOfMemoryError você seria capaz de fechar o aplicativo regularmente (mesmo talvez libere memória e continuar), em alguns outros, não há muito que você pode fazer.
Muito raramente.
Eu diria apenas no nível superior de um fio para tentar emitir uma mensagem com a razão de um fio a morrer. Se você está em uma estrutura que faz esse tipo de coisa por você, deixe isso para a estrutura.Um Error
, normalmente, não deve ser pego, como indica uma condição anormal que nunca deve ocorrer.
Da especificação da API Java para a Error
classe:
An
Error
é uma subclasse deThrowable
isso indica problemas graves que uma aplicação razoável não deve tentar pegar. A maioria desses erros são condições anormais. [...]Não é necessário um método para declarar em sua cláusula de arremesso qualquer subclasses de Erro que pode ser jogado durante o execução do método, mas não apanhado, uma vez que estes erros são condições anormais que nunca deveriam ocorrer.
Como a especificação menciona, um {[[0]} só é jogado em circunstâncias que são
As Chances são de que, quando um Error
ocorre, há muito pouco que o aplicativo pode fazer, e, em algumas circunstâncias, a Máquina Virtual Java em si, pode ser em um estado instável (como VirtualMachineError
)
Embora um Error
é uma subclasse de Throwable
o que significa que pode ser capturada por uma cláusula try-catch
, mas provavelmente não é realmente necessária, pois a aplicação estará num estado anormal quando um Error
é lançado pelo JVM.
Existe também uma pequena secção sobre este tópico na secção 11.5 A hierarquia de excepções da especificação da linguagemJava, 2.A edição .
Se você é louco o suficiente para estar a criar uma nova estrutura de teste unit, o seu test runner provavelmente vai precisar de apanhar java.idioma.Erro de afirmação de qualquer caso de teste.
Caso contrário, consulte outras respostas.Uma aplicação só deve capturar instâncias desta classe se tiver de limpar depois de ser exterminado assíncronamente. Se o ThreadDeath for apanhado por um método, é importante que ele seja derrubado assim que o fio realmente morre.
Muito, muito raramente.
Só o fiz por um caso muito específico. Por exemplo, java.idioma.O erro não declarado poderia ser lançado se dois carregadores independentes carregassem o mesmo DLL. (Eu concordo que eu deveria mover o jarro para um classloader compartilhado)Mas o caso mais comum é que você precisava de registro para saber o que aconteceu quando o usuário vem reclamar. Você quer uma mensagem ou um popup para o usuário, em vez de silenciosamente morto.
Mesmo programador em C / C++, eles introduza um erro e diga algo que as pessoas não compreendam antes de sair (por exemplo, falha de memória).
Numa aplicação Android estou a apanhar um java.idioma.Verificerror . Uma biblioteca que estou usando não vai funcionar em dispositivos com uma versão antiga do SO e o código da biblioteca vai lançar tal erro. Eu poderia, naturalmente, evitar o erro ao verificar a versão do sistema operacional no tempo de execução, mas:
- O SDK mais antigo suportado poderá mudar no futuro para a biblioteca específica
- o bloco de erro de tentativa de captura faz parte de um mecanismo de recuo maior. Alguns dispositivos específicos, embora é suposto apoiar a biblioteca, abrir excepções. Apanho o Verificador e todas as excepções para usar uma solução alternativa.
Idealmente não devemos lidar com erros de captura. Mas pode haver casos em que precisamos de o fazer, com base na exigência de enquadramento ou aplicação. Digamos que tenho um servidor de processamento XML que implementa O analisador de DOM que consome mais memória. Se existir um requisito como o Parser thread não deve ser morto quando ele obtém OutOfMemoryError , em vez disso, ele deve lidar com ele e enviar uma mensagem/mail para o administrador da aplicação/framework.
Idealmente nunca devemos pegar erro em nossa aplicação Java, pois é uma condição anormal. A aplicação estaria em estado anormal e poderia resultar em carshing ou dar algum resultado seriamente errado.
Pode ser adequado detectar erros nos testes unitários que permitam verificar uma afirmação. Se alguém desactiva afirmações ou de outra forma apaga a afirmação que você gostaria de saber
Ele também vai depender do computador em execução, o estado de memória atual, então não há maneira de testar, tentar e fazer o seu melhor. Só terá um resultado perigoso.
Também diminuirá a legibilidade do seu código.