Throws e Throw new

Andei lendo bastante a respeito de tratamento de erros e fiquei um pouquinho confuso quanto ao uso da instrução throw.

Por exemplo, quando e como exatamente deve ser usado um throw e um throw new?

A palavra reservada throws vai na assinatura do método e indica que este método poderá lançar uma exceção que deve ou ser relançada ou capturada pelo método que a está chamando.

public void foo (int x, int y) throws Exception 

A palavra reservada throw new serve para lançar a exceção de dentro do corpo do método como em:

try { // Faz algo } catch(Exception e){ throw new Exeption(); }

A parte de artigos do GUJ traz algo a respeito de tratamento de exceções. Acho que pode ser uma boa.
Att.

1 curtida

Obrigado. Poderia postar um exemplo prático (pode ser simples mesmo) em que seria útil o uso de um “throw new”?

Vale lembrar que a instrução não é throw new, mas somente throw. O new é para criar um novo objeto Exception e não faz parte do throw, você também pode lançar um objeto que já existe.

1 curtida

Segue:

[code]public class Teste {

public int foo(String x) throws NumberFormatException {     //Método que az uma conversão de um String para int
    return(Integer.parseInt(x));             //A assinatura do método diz que pode lançar uma NumberFormatException
}                                                       //Mas o método não trata, ao invés disso lança a exceção com throws

public void bar() throws NumberFormatException {
    try {
        int a = this.foo("x");                                  //Chama o método foo() que declara lançar uma exceção.
        System.out.println("String convertida em int é: " + a); //Este método deve ou capturar ou relançar a exceção que recebeu.
    } catch(NumberFormatException e){              //Este catch captura a exceção.
        throw new NumberFormatException();        //Mas aqui dentro ele resolve relançar ela. 
                                                                      //Usa throw, e new para criar o objeto. E, na assinatura deve haver um throws.
    }
}

public static void main(String args[]){
    try {                                                       //Esse aqui chama bar() que lança a exceção que pegou de foo.
        Teste teste = new Teste();                   //Este deve ou capturar ou relançar.
        teste.bar();    
    } catch(NumberFormatException e){         //Ele resolve capturar e fazer o tratamento necessário.
        System.out.println("Capturei a exceção lançada no método foo()"); //Final, encerrou a pilha de propagação da exception.
        e.printStackTrace();
    }
}

}[/code]
A regra para tratamento de exceções é: declare ou capture.

Qualquer dúvida posta aí…

Sensacional Fernando. Já deu uma ótima clareada e já vejo outros exemplos que tenho com maior facilidade.

Então, o throws declarado na assinatura do método diz respeito a “Exception original”. Ao optar por capturar através do catch no outro método bar(), eu tenho a opção de criar um novo objeto throw (throw new) para relançar essa excessão, correto?

Agora se entendi realmente bem, você poderia ter tratado a excessão diretamente no método main sem a necessidade de criar o “throw new” dentro do catch no método bar(), porém preferiu relançar a excessão somente para fim de esclarecer minha duvida correto?

Além disso tentando ir só um pouquinho mais a fundo, no método bar(), poderia ser o caso de você relançar a excessão, para uma “excessão de negócio” criado por mim mesmo certo? Tipo relançar o NumberFormatException para outra classe que eu criei estendendo Exception, chamada ficticialmente por exemplo, “NumeroInvalidoException”, ou não?

Por exemplo, dentro do método bar():

 } catch(NumberFormatException e){
            throw new NumeroInvalidoException();
}

sgsdg

Recomendo a leitura desses 3 textos, para não se perder no uso de exceções:
-> Exceções: Conceitos
-> Exceções: Boas Práticas, Más Práticas
-> Exceções: Classes Utilitárias

O que posso dizer de principal que há nesse texto é, seja especifico! … e use as exceções ja existentes sempre q possivel…

Um exemplo de uso que fica facil

public void setNome(String nome) { if(nome.length() > 45) throw new MaximumSizeException(this,"nome",nome,45); }

por exemplo, essa exceção, MaximumSizeException é uma exceção que eu criei, que extends IllegalArgumentException…
Ou seja, uma exeção especifica, gerada quando o argumento nome, é passado de forma ilegal, nesse caso especifico, qunado seu tamnho é maior que 45…
na minha exceção varios parametros são passados de forma a rastrear o erro… a classe source, ou seja, fonte do erro, (this) … o nome da propriedade referente ao argumento que gerou o erro, no caso "nome" … o valor da propriedade que gerou o erro (nome) … o valor maximo do comprimento do nome (45) …

ai depois é possivel resgatar essas informações quando a exceção é lançada…

Correto, diz respeito a exceção original, recebida a partir de outro método. Ou então é uma exceção nova, recém lançada por este método mesmo.

[quote=stone010]Agora se entendi realmente bem, você poderia ter tratado a excessão diretamente no método main sem a necessidade de criar o “throw new” dentro do catch no método bar(), porém preferiu relançar a excessão somente para fim de esclarecer minha duvida correto?
[/quote]

Exato. Mas mesmo assim a assinatura do método bar deve permanecer igual. Somente o que tu tiraria seria o try/catch. A assinatura permaneceria igual para não quebrar a regra declare ou capture. Deixando somente a assinatura você está dizendo que está declarando/relançando.

[quote=stone010]Além disso tentando ir só um pouquinho mais a fundo, no método bar(), poderia ser o caso de você relançar a excessão, para uma “excessão de negócio” criado por mim mesmo certo? Tipo relançar o NumberFormatException para outra classe que eu criei estendendo Exception, chamada ficticialmente por exemplo, “NumeroInvalidoException”, ou não?

Por exemplo, dentro do método bar():

} catch(NumberFormatException e){ throw new NumeroInvalidoException(); } [/quote]

Sim, você poderia fazer isso.

:thumbup:

blz Fernando, valews jow, isso esclarece muita coisa cara.
vlws lavieri…

abraços

qual o efeito de lançar um objeto que ja existe?
vai retornar o que ?

fiquei na duvida :?:

qual o efeito de lançar um objeto que ja existe?
vai retornar o que ?

fiquei na duvida :?: [/quote]

esse aqui…

try { session.beginTrasaction(); session.save(minhaEntidade); session.commit(); } catch(Exception ex) { //Eu não quero tratar totalmente a exceção, so dar rollback na trazação em caso erro. session.rollback(); //depois do rollbak dado, não vou ficar com a exceção, vou lançada novamente, para quem for tratala... throw ex; } finally { session.close(); //aqui garanto que sempre fecho a sessão, ocorrendo erro ou não }

1 curtida