Por que “lança exceção” é necessário ao chamar uma função?

97
class throwseg1
{
    void show() throws Exception
    {
        throw new Exception("my.own.Exception");
    }

    void show2() throws Exception  // Why throws is necessary here ?
    {
        show();
    }

    void show3() throws Exception  // Why throws is necessary here ?
    {
        show2();
    }

    public static void main(String s[]) throws Exception  // Why throws is necessary here ?
    {
        throwseg1 o1 = new throwseg1();
        o1.show3();
    }
}

Por relatórios de compilador que os métodos show2(), show3()e main()tem

exceção não relatada Exceção que deve ser capturada ou declarada para ser lançada

quando eu removo throws Exceptionesses métodos?

nr5
fonte
2
@PaulTomblin main certamente pode ser declarado para lançar Exception. Se isso acontecer, a JVM será encerrada. Isso é o mais próximo de ignorá-lo que o compilador permitirá.
Taymon
Quando o método chamado ( Methdod1 ) lança Exception, temos que definir o método de chamada ( Método2 ) com throws Exception; se não estivermos tratando dessa exceção no método de chamada. O objetivo deste é dar heads up para o método de chamada ( method3 ) de Method2 que uma exceção pode ser lançada por Method2 e você deve lidar com isso aqui, então ele pode interromper o seu programa.
Rito
Da mesma forma, se Method3 não está tratando a exceção em seu corpo, então, ele teve que definir throws Exceptionem sua definição de método para avisar seu método de chamada. extensão do comentário anterior
Rito

Respostas:

144

Em Java, como você deve saber, as exceções podem ser categorizadas em duas: uma que precisa da throwscláusula ou deve ser tratada se você não especificar uma e outra que não. Agora, veja a seguinte figura:

insira a descrição da imagem aqui

Em Java, você pode lançar qualquer coisa que estenda a Throwableclasse. No entanto, você não precisa especificar uma throwscláusula para todas as classes. Especificamente, as classes que são um Errorou RuntimeExceptionou qualquer uma das subclasses desses dois. No seu caso, Exceptionnão é uma subclasse de um Errorou RuntimeException. Portanto, é uma exceção verificada e deve ser especificada na throwscláusula, se você não tratar essa exceção em particular. É por isso que você precisava da throwscláusula.


Do tutorial Java :

Uma exceção é um evento, que ocorre durante a execução de um programa, que interrompe o fluxo normal das instruções do programa.

Agora, como você sabe, as exceções são classificadas em duas: marcadas e não marcadas. Por que essas classificações?

Exceção verificada: são usados ​​para representar problemas que podem ser recuperados durante a execução do programa. Eles geralmente não são culpa do programador. Por exemplo, um arquivo especificado pelo usuário não é legível, ou nenhuma conexão de rede disponível, etc. Em todos esses casos, nosso programa não precisa sair, em vez disso, ele pode executar ações como alertar o usuário ou entrar em um fallback mecanismo (como trabalho offline quando a rede não está disponível), etc.

Exceções não verificadas: Novamente, elas podem ser divididas em duas: Errors e RuntimeExceptions. Uma razão para eles serem desmarcados é que eles são numerosos e necessários para lidar com todos eles irão bagunçar nosso programa e reduzir sua clareza. O outro motivo é:

  • Exceções de tempo de execução: geralmente ocorrem devido a uma falha do programador. Por exemplo, se ocorrer um ArithmeticExceptionde divisão por zero ou um ArrayIndexOutOfBoundsExceptionocorrer, é porque não somos cuidadosos o suficiente em nossa codificação. Eles acontecem geralmente devido a alguns erros na lógica do nosso programa. Portanto, eles devem ser limpos antes que nosso programa entre em modo de produção. Eles são desmarcados no sentido de que nosso programa deve falhar quando ocorrer, para que nós, programadores, possamos resolvê-lo no momento do desenvolvimento e do próprio teste.

  • Erros: Erros são situações das quais geralmente o programa não consegue se recuperar. Por exemplo, se StackOverflowErrorocorrer um , nosso programa não pode fazer muito, como aumentar o tamanho da pilha de chamada de função do programa. Ou, se OutOfMemoryErrorocorrer um , não podemos fazer muito para aumentar a quantidade de RAM disponível para nosso programa. Nesses casos, é melhor sair do programa. É por isso que eles são desmarcados.

Para obter informações detalhadas, consulte:

Jomoos
fonte
o que obtive de sua resposta é que a classe Error e suas subclasses e a classe RuntimeException e suas subclasses estão sob exceção não verificada (como System.out.println (5/0); não há necessidade de lançar, pois é uma exceção de tempo de execução, mas ainda podemos aplicar try catch) e a classe Exception é verificada, então precisamos declarar a cláusula throws nesse método e em todos os métodos que a chamam
nr5
Mais uma pergunta: se as exceções são categorizadas em não verificadas e verificadas, principalmente as não verificadas (erros de runtime) para evitar mais erros durante o tempo de compilação?
nr5
@Jomoos - diga que o código dentro de um método lança IOException. Então, é correto colocar "throws Exception" na declaração do método?
MasterJoe
oh. Agora eu entendi. há uma exceção às regras da hierarquia de exceções. Faz. Perfeito. Sentido. Obrigado Java.
JJS de
25

Java requer que você trate ou declare todas as exceções. Se você não estiver manipulando uma exceção usando um bloco try / catch, ela deve ser declarada na assinatura do método.

Por exemplo:

class throwseg1 {
    void show() throws Exception {
        throw new Exception();
    }
}

Deve ser escrito como:

class throwseg1 {
    void show() {
        try {
            throw new Exception();
        } catch(Exception e) {
            // code to handle the exception
        }
    }
}

Desta forma, você pode se livrar da declaração "throws Exception" na declaração do método.

jebar8
fonte
7
Todas as exceções que não são subclasses de RuntimeException, claro .
yshavit
se houver alguma outra classe como Exception que está marcada?
nr5
1
O que você quer dizer? Como todos os objetos de exceção têm "Exception" como classe base, se você capturar um objeto "Exception" (como no meu exemplo), ele capturará qualquer exceção que seja lançada. Para ser mais específico (já que diferentes exceções provavelmente exigirão diferentes maneiras de lidar com as coisas), você deve ter vários blocos catch.
jebar8
se eu dissesse que as exceções verificadas precisam ser tratadas em tempo de compilação e capturadas em tempo de execução. Estou certo ? se sim, então formular a mesma frase para exceção não verificada seria?
nr5
@ jebar8 - você está confundindo Java com .NET - em Java, os descartáveis ​​devem herdar Throwable(herdar Exceptiontambém funciona, porque estende Throwable, mas não é obrigatório).
BrainSlugs83
4

Exceptioné uma classe de exceção verificada. Portanto, qualquer código que chame um método que declare que throws Exceptiondeve tratá-lo ou declará-lo.

Taymon
fonte
Cada método na cadeia é declarado para lançar Exception, incluindo main. Então, onde está o problema?
Paul Tomblin
@PaulTomblin estou perguntando por que é necessário escrever lança exceção nas funções de chamada, chamando uma função que lança uma exceção
nr5
Ok, não entendi por que você estava perguntando sobre um erro do compilador que não estava realmente recebendo do código que postou. É uma maneira estranha de perguntar.
Paul Tomblin
4

A throws Exceptiondeclaração é uma maneira automatizada de controlar os métodos que podem lançar uma exceção por motivos previstos, mas inevitáveis. A declaração é normalmente específica sobre o tipo ou tipos de exceções que podem ser lançadas, como throws IOExceptionou throws IOException, MyException.

Todos nós temos ou iremos, eventualmente, escrever um código que pára inesperadamente e relata uma exceção devido a algo que não previmos antes de executar o programa, como divisão por zero ou índice fora dos limites. Como os erros não eram esperados pelo método, eles não puderam ser "capturados" e tratados com uma cláusula try catch. Quaisquer usuários desavisados ​​do método também não saberiam dessa possibilidade e seus programas também parariam.

Quando o programador sabe que certos tipos de erros podem ocorrer, mas gostaria de lidar com essas exceções fora do método, o método pode "lançar" um ou mais tipos de exceções ao método de chamada em vez de tratá-los. Se o programador não declarasse que o método (poderia) lançar uma exceção (ou se Java não tivesse a capacidade de declará-la), o compilador não poderia saber e caberia ao futuro usuário do método saber sobre, capturar e manipular quaisquer exceções que o método possa lançar. Como os programas podem ter muitas camadas de métodos escritos por muitos programas diferentes, torna-se difícil (impossível) manter o controle de quais métodos podem lançar exceções.

Mesmo que o Java tenha a capacidade de declarar exceções, você ainda pode escrever um novo método com exceções não tratadas e não declaradas, e o Java irá compilá-lo e você pode executá-lo e esperar o melhor. O que o Java não permitirá que você faça é compilar seu novo método se ele usar um método que foi declarado como lançando exceção (ões), a menos que você trate a (s) exceção (ões) declarada (s) em seu método ou declare seu método como lançando o mesmo exceção (ões) ou se houver várias exceções, você pode manipular algumas e lançar o resto.

Quando um programador declara que o método lança um tipo específico de exceção, é apenas uma forma automatizada de avisar outros programadores usando o método de que uma exceção é possível. O programador pode então decidir tratar a exceção ou passar o aviso declarando o método de chamada como também lançando a mesma exceção. Uma vez que o compilador foi avisado que a exceção é possível neste novo método, ele pode verificar automaticamente se futuros chamadores do novo método tratam a exceção ou declaram-na e obrigam a que um ou outro aconteça.

O bom desse tipo de solução é que, quando o compilador relata, Error: Unhandled exception type java.io.IOExceptionele fornece o arquivo e o número da linha do método que foi declarado para lançar a exceção. Você pode então escolher simplesmente passar a bola e declarar seu método também "lança IOException". Isso pode ser feito até o método principal, onde faria com que o programa parasse e relatasse a exceção ao usuário. No entanto, é melhor capturar a exceção e lidar com ela de uma maneira agradável, explicando ao usuário o que aconteceu e como corrigi-lo. Quando um método captura e trata a exceção, ele não precisa mais declarar a exceção. A bola pára por aí, por assim dizer.

dansalmo
fonte
0
package javaexception;


public class JavaException {
   void show() throws Exception
    {
        throw new Exception("my.own.Exception");
    }

void show2() throws Exception  // Why throws is necessary here ?
{
    show();
}

void show3() throws Exception  // Why throws is necessary here ?
{
    show2();
}
public static void main(String[] args) {

   JavaException a = new JavaException();

   try{
   a.show3();
   }catch(Exception e){
       System.out.println(e.getMessage());
   }
}

Apenas pequenas mudanças em seu programa. O que parece ser mal compreendido por muitos em relação ao problema principal, é sempre que você lança uma exceção, você precisa tratá-la, não é necessário no mesmo lugar (ex. Método show1,2,3 em seu programa), mas você deve no primeiro método de chamada dentro do 'principal'. em uma palavra, há 'jogar', deve haver 'pegar / tentar', mesmo que não seja o mesmo método onde ocorre a exceção.

tawess
fonte
0
void show() throws Exception
{
    throw new Exception("my.own.Exception");
}

Como há exceção verificada no método show (), que não está sendo tratada nesse método, usamos a palavra-chave throws para propagar a exceção.

void show2() throws Exception //Why throws is necessary here ?
{
show();
}

Como você está usando o método show () no método show2 () e propagou a exceção, pelo menos, você deve tratar aqui. Se você não está lidando com a exceção aqui, está usando a palavra-chave throws. Portanto, essa é a razão para usar a palavra-chave throws na assinatura do método.

Aditya
fonte
0

Se você propagar a exceção declarando a diretiva throws na assinatura do método atual, então em algum lugar acima da linha ou pilha de chamadas uma construção try / catch deve ser usada para tratar a exceção.

Beaumont Muni
fonte
Este comentário deve ser adicionado à seção de comentários, pois não fornece uma resposta verificável ou um exemplo de uma. - stackoverflow.com/help/how-to-answer
Paul Dawson
-1

Basicamente, se você não estiver tratando a exceção no mesmo lugar em que a está lançando, poderá usar "lança exceção" na definição da função.

Shahzeb Sheikh
fonte