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?
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.
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.
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
}