Essas declarações de código são equivalentes? Existe alguma diferença entre eles?
private void calculateArea() throws Exception {
....do something
}
private void calculateArea() {
try {
....do something
} catch (Exception e) {
showException(e);
}
}
Respostas:
Sim, há uma grande diferença - o último engole a exceção (mostrando, é certo), enquanto o primeiro vai deixá-la se propagar. (Presumo que
showException
isso não o relembre.)Portanto, se você chamar o primeiro método e "fazer algo" falhar, o chamador terá que lidar com a exceção. Se você chamar o segundo método e "fazer algo" falhar, o chamador não verá nenhuma exceção ... o que geralmente é uma coisa ruim, a menos que
showException
tenha genuinamente tratado a exceção, corrigido o que quer que esteja errado e, geralmente, tenha certeza quecalculateArea
alcançou seu propósito.Você vai ser capaz de dizer isso, porque você não pode chamar o primeiro método, sem qualquer captura
Exception
-se ou declarar que seu método pode jogá-lo também.fonte
Primeiro
throws Exception
, então o chamador precisa lidar com oException
. O segundo captura e trataException
internamente, para que o chamador não precise fazer nenhum tratamento de exceção.fonte
Sim. A versão que declara
throws Exception
exigirá o código de chamada para tratar a exceção, enquanto a versão que explicitamente trata isso não.ou seja, simplesmente:
vs. transferir o fardo de lidar com a exceção para o chamador:
fonte
Sim, existe uma grande diferença entre eles. No primeiro bloco de código, você passa a exceção para o código de chamada. No segundo bloco de código, você mesmo lida com isso. O método correto depende inteiramente do que você está fazendo. Em alguns casos, você deseja que seu código trate a exceção (se um arquivo não for encontrado e você deseja criá-lo, por exemplo), mas em outros, você deseja que o código de chamada trate a exceção (um arquivo não foi encontrado e eles precisam especificar um novo ou criá-lo).
De modo geral, você não deseja capturar uma exceção genérica. Em vez disso, você desejará capturar apenas alguns específicos, como
FileNotFoundException
ouIOException
porque podem significar coisas diferentes.fonte
Existe um cenário particular onde não podemos usar arremessos, temos que usar try-catch. Existe uma regra "Um método sobrescrito não pode lançar nenhuma exceção extra que não seja aquela que sua classe pai está lançando". Se houver alguma exceção extra que deve ser tratada usando try-catch. Considere este trecho de código. Existe uma classe base simples
e sua classe derivada:
Quando temos que chamar thread.sleep (), somos forçados a usar try-catch, aqui não podemos usar:
porque o método sobrescrito não pode lançar exceções extras.
fonte
Suponho que por "idêntico" você está se referindo ao comportamento.
O comportamento de uma função pode ser determinado por:
1) Valor devolvido
2) Exceções lançadas
3) Efeitos colaterais (ou seja, mudanças no heap, sistema de arquivos, etc.)
Nesse caso, o primeiro método propaga qualquer exceção, enquanto o segundo não lança nenhuma exceção verificada e também engole a maioria das exceções não verificadas, de modo que o comportamento É diferente.
No entanto, se você garantir que "fazer algo" nunca lança uma exceção, o comportamento seria idêntico (embora o compilador exija que o chamador trate a exceção, na primeira versão)
--editar--
Do ponto de vista do design da API, os métodos são completamente diferentes em seu contrato. Além disso, lançar a classe Exception não é recomendado. Tente lançar algo mais específico para permitir que o chamador trate melhor a exceção.
fonte
Se você lançou uma exceção, o método filho (que substitui isso) deve lidar com a exceção
exemplo:
fonte
Muitas vezes, você deseja que o chamador trate a exceção. Digamos que você faça o chamador chamar um método que chama outro método que chama outro método, em vez de cada método tratar a exceção, você pode tratá-lo apenas no chamador. A menos que você queira fazer algo em um dos métodos quando esse método falhar.
fonte
O chamador desse método precisará capturar essa exceção ou declará-la para ser relançada em sua assinatura de método.
No exemplo de bloco try-catch abaixo. O chamador deste método não precisa se preocupar em lidar com a exceção, pois ela já foi tratada.
fonte
Isso lança a exceção, de modo que o chamador é responsável por lidar com essa exceção, mas se o chamador não lidar com a exceção, então pode ser que ele será fornecido para jvm, o que pode resultar no encerramento anormal do programa.
Considerando que no segundo caso:
Aqui, a exceção é tratada pelo receptor, portanto, não há chance de encerramento anormal do programa.
Try-catch é a abordagem recomendada.
IMO,
Lança a palavra-chave usada principalmente com exceções verificadas para convencer o compilador, mas não garante o encerramento normal do programa.
Lança o delegado de palavra-chave a responsabilidade de tratamento de exceção para o responsável
pela chamada (JVM ou outro método).
A palavra-chave throws é necessária apenas para exceções verificadas; para exceções não verificadas, não há uso da palavra-chave throws.
fonte