[b]Olá pessoal!
Precisaria de uma dúvida com uma Exception.
Gostaria de saber porque a minha classe diz que a exceção não foi tratada (na main).[/b]
public class Main
{
public static int f(int x, int y) throws ArithmeticException
{
try
{
System.out.println(" 1 ");
return x/y;
}
catch(ArithmeticException ex)
{
System.out.println(" 2 ");
throw ex;
}
finally
{
System.out.println(" 3 ");
}
}
public static int g(int x, int y) throws Exception
{
try
{
System.out.println(" 4 ");
return x/y;
}
catch(ArithmeticException ex)
{
System.out.println(" 5 ");
throw ex;
}
finally
{
System.out.println(" 6 ");
}
}
public static void main(String[] args)
{
g(10, 0);
}
}
Se eu tiro throws Exception, não é mais dito que a exceção não foi tratada. Se eu tiro ArithmeticException do catch e troco por Exception, o mesmo errp persiste. Por quê?
Por acaso é proibido ter um throw Exception e embaixo, o seu tratamento?
se você deixa o throws, isso diz para o método que invoca ele, que essa exceção tem que ser tratada…
se você trata ela (try/catch) dentro do método, não precisa ter o throws na assinatura, porque não precisa tratar 2x hehe
ou você trata ela com um bloco try/catch, ou adiciona o throws na assinatura, fazendo com que o método(no seu caso o main) que invoca esse método(no seu caso o f) tenha que tratá-lo.
Primeiro entenda o que é o throws. Ele dispensa o uso do try/catch. Ele vai jogar a responsabilidade de tratar o erro para a classe/método que o chamou.
Por isso, ao tirar o throws ArithmeticException e mantendo o try/catch roda normalmente.
Se vai usar o throws, tire todos os blocos try/catch referentes à mesma exception se, vai usar try/catch, tire o throws correspondente…
[quote=drsmachado]Primeiro entenda o que é o throws. Ele dispensa o uso do try/catch. Ele vai jogar a responsabilidade de tratar o erro para a classe/método que o chamou.
Por isso, ao tirar o throws ArithmeticException e mantendo o try/catch roda normalmente.
Se vai usar o throws, tire todos os blocos try/catch referentes à mesma exception se, vai usar try/catch, tire o throws correspondente…[/quote]
Isso que você disse não é uma regra. É boa programação. Tanto é que a primeira função do código funciona normalmente (caso eu troque g por f, com os mesmos parâmetros).
[code]public static int f(int x, int y) throws ArithmeticException
{
try
{
System.out.println(" 1 ");
return x/y;
}
catch(ArithmeticException ex)
{
System.out.println(" 2 ");
throw ex;
}
finally
{
System.out.println(" 3 ");
}
} [/code]
O trecho acima funciona perfeito, com f(10, 0).
[quote=digaoneves]se você deixa o throws, isso diz para o método que invoca ele, que essa exceção tem que ser tratada…
se você trata ela (try/catch) dentro do método, não precisa ter o throws na assinatura, porque não precisa tratar 2x hehe
ou você trata ela com um bloco try/catch, ou adiciona o throws na assinatura, fazendo com que o método(no seu caso o main) que invoca esse método(no seu caso o f) tenha que tratá-lo.[/quote]
O throws somente diz que uma exceção pode acontecer. A obrigatoriedade de tratar, seja por catch ou por declare, é um requisito somente de exceções verificadas, como uma IOException. Se eu não tratar, será gerado uma mensagem padrão na pilha.
e por acaso o bloco catch é executado todas as vezes?
pra mim é a mesma coisa, uma possível exceção tratadas em situações (chamadas) diferentes.
agora ter os 2 obriga você a tratar o mesmo duas vezes não concorda? uma vez dentro do método em si, e outra vez no método que o invoca
Determinados métodos obrigam você a indicar que, ou a classe que está invocando-o irá tratar possível erro ou que aquele trecho seja circundado com try/catch (tente instanciar uma classe por reflection, usando o Class.forName(“String”); e veja o que acontece se não colocar um dos dois).
Se vocë teve o mínimo interesse em ver qual o motivo pelo qual a IDE acusa erro quando usa a chamada ao método g, teria percebido que ele trata de uma menção ao throws Exception, cuja chamada não é tratada.
Enfim, isto fica a teu critério, camarada.
[quote=digaoneves]e por acaso o bloco catch é executado todas as vezes?
pra mim é a mesma coisa, uma possível exceção tratadas em situações (chamadas) diferentes.
agora ter os 2 obriga você a tratar o mesmo duas vezes não concorda? uma vez dentro do método em si, e outra vez no método que o invoca[/quote]
Bem, olha o que entendi…
O throws indica que poderá ser lançado uma exceção. Como Exception é uma exceção verificada, exige que eu a trate. Eu posso tratar dentro do método g() ou na chamada de g(), na main. No último caso, colocaria a chamada em try/catch e pronto. Porém, eu quero tratar dentro do método. Se eu colocar mais um catch, com Exception, ainda diz que eu não tratei a exceção.
Estou achando que não pode usar throws Exception no método se você pretende tratá-la nela.
É isso?
É isso que a gente ta tentando explicar
se você vai tratar dentro do método, só apague o throws…
[quote=digaoneves]É isso que a gente ta tentando explicar
se você vai tratar dentro do método, só apague o throws…
[/quote]
Mas porque somente dá erro com o throws Exception e com as demais não dá? Tem throws ArithmeticException e tratada dentro do método.
O método f() funciona perfeitamente (trocando g() por f() na main).
[quote=ECO2004]
Mas porque somente dá erro com o throws Exception e com as demais não dá? Tem throws ArithmeticException e tratada dentro do método.
O método f() funciona perfeitamente (trocando g() por f() na main).[/quote]
Espertão, troca o catch(ArithmeticException ex)
do método g por catch(Exception ex)
e testa.
Você está dizendo que, independente do código, você poderá lançar uma exception. Porém, em nenhum lugar há um tratamento para esta exception.
Pense no seguinte, se você tem um método que pode retornar null ou uma String e só trata a String e não o null, em algum momento pode ter um NullPointerException, certo?
[quote=drsmachado][quote=ECO2004]
Mas porque somente dá erro com o throws Exception e com as demais não dá? Tem throws ArithmeticException e tratada dentro do método.
O método f() funciona perfeitamente (trocando g() por f() na main).[/quote]
Espertão, troca o catch(ArithmeticException ex)
do método g por catch(Exception ex)
e testa.
Você está dizendo que, independente do código, você poderá lançar uma exception. Porém, em nenhum lugar há um tratamento para esta exception.
Pense no seguinte, se você tem um método que pode retornar null ou uma String e só trata a String e não o null, em algum momento pode ter um NullPointerException, certo?[/quote]
Há um tratamento. O tratamento está no bloco catch(Exception ex).
public static int f(int x, int y) throws Exception
{
try
{
System.out.println(" 1 ");
return x/y;
}
catch(Exception ex)
{
return -1;
}
finally
{
System.out.println(" 3 ");
}
}
E você leu a parte do “do método g por”, certo?
Sugiro fazer o seguinte:
1 - Refaça a classe toda, sem qualquer tratamento de exception.
2 - Inclua apenas try/catch(Exception e)
3 - Retire todos os try/catch e coloque apenas throws Exception
4 - Não altere o modelo anterior. Coloque try/catch(Exception e) na chamada ao método em questão (ou ambos)
5 - Desfaça tudo e coloque try/catch(ArithmeticException ae) nos métodos
6 - Troque o try/catch por throws ArithmeticException sem tratamento em qualquer lugar
7 - Trate com try/catch na chamada dos metodos
Se mesmo assim continuar a não entender, me desculpe, mas programar não é para você. Pare enquanto é tempo e vá ser político.
No caso do bloco
catch(Exception ex)
irá executar em todas as exceções
você pode ter varios blocos catch para executar coisas específicas para cada tipo de exceção partindo da menos genérica pra a mais genérica ex.
try {
//codigo
} catch (NullPointerException ex) {
// Codigo
} catch (Exception ex) {
// Codigo
}
dieguittom, você pode ter, também, vários throws
thros ArithmeticException, NullPointerException, NoSuchMethodException, Exception
A questão é…
Em algum momento, estas coisas precisam ser tratadas.
Correto
e como você já disse:
ou usa try/catch para tratar ou usa throws para jogar a responsabilidade de tratar o erro para a classe/método que o chamou.
[quote=dieguittom]Correto
e como você disse
ou usa try/catch para tratar ou usa throws para jogar a responsabilidade de tratar o erro para a classe/método que o chamou.[/quote]
Se lançar com throws, tem que tratar o erro na chamada.
Bom dia a todos.
O que voce precisa entender é que quando voce lança a exceção com throws Exception para que outro método invocador, ela tem que ser tratada de qualquer forma no método invocador, e no seu caso, voce tem que definir um try…catch dentro do método starter public void main(…), se voce não fizer o tratamento ali, vai dar erro e é isso que o pessoal está tentando te explicar. Execute o código abaixo e vê o que acontece.
public class Main
{
public static int f(int x, int y) throws Exception
{
try
{
System.out.println(" 1 ");
return x/y;
}
catch(ArithmeticException ex)
{
System.out.println(" 2 ");
throw ex;
}
finally
{
System.out.println(" 3 ");
}
}
public static int g(int x, int y) throws Exception
{
try
{
System.out.println(" 4 ");
return x/y;
}
catch(ArithmeticException ex)
{
System.out.println(" 5 ");
throw ex;
}
finally
{
System.out.println(" 6 ");
}
}
public static void main(String[] args)
{
try {
f(10, 0);
} catch (Exception ex) {
System.out.println(ex.getMessage());
}
}
}
Repare que mesmo que a exceção ArithmeticException seja tratata no método inicial, o disparo da exceção tratada no método starter main só será efetuado se houver qualquer outra exceção que não seja ArithmeticException, contudo, isto não constitui uma boa prática de programação. Se voce pretende tratar todas as exceções e não sabe o nome de todas elas, use a classe Exception que é mãe de todas as classes de Exceção, ou seja, todas as exceções herdam (extendem) de Exception, assim o seu código ficaria limpo desta forma:
public class Main
{
public static int f(int x, int y)
{
try
{
System.out.println(" 1 ");
return x/y;
}
catch(Exception ex)
{
System.out.println(" 2 \n" + ex.getMessage()");
}
finally
{
System.out.println(" 3 ");
}
}
public static void main(String[] args)
{
f(10,0);
}
}
// ou assim:
public class Main
{
public static int f(int x, int y) throws Exception
{
return x/y;
}
public static void main(String[] args)
{
try {
f(10, 0);
} catch (Exception ex) {
System.out.println(ex.getMessage);
}
}
}
Respondendo à pergunta original…
O compilador requer que você coloque o “throws” no main porque na definição do método você declarou “throws Exception”. Isso indica que aquele método pode arremessar uma exception do tipo Exception. Algumas exceções podem ser arremessadas sem ninguém tratar (todas as derivadas do RuntimeException). A ArithmeticException é uma delas. A Exception não.
Com a linha do “g”, o compilador vê: alguém arremessa uma exceção que deve ser tratada e não é por ninguém. Por isso, ele chia. Com o “f”, ele vê "ah, é uma RuntimeException, ninguém precisa tratar (mas pode tratar se quiser).
Com o “throws” no main, você delega o tratamento para quem chama ela.
Ficou claro?!