Dúvida Interessante - throw

11 respostas
thundercas

Fala galera, beleza???

Estou com a seguinte dúvida… Peço que observem os 2 trechos de código abaixo:

try {
    String s = "x";
    int i = Integer.parseInt(x);
} catch (NumberFormatException e) {
    e.printStackTrace();
}
// Mais código aqui

#################

try {
    String s = "1";
    int i = Integer.parseInt(x);
    throw new NumberFormatException("Erro");
} catch (NumberFormatException e) {
    e.printStackTrace();
}
// Mais código aqui

A dúvida é a seguinte: Qual a diferença no tratamento da exceção nos 2 casos acima??? Teoricamente, os 2 trechos deveriam efetuar exatamente o mesmo tratamento, não???

A impressão q tenho é ao utilizar o throw o código abaixo de chave que fecha o catch não é executado, já quando ocorre a exceção naturalmente, o trecho pós catch é executado normalmente… É isso mesmo?? Mas não deveriam ser iguais os tratamentos?? :?

Se alguém puder esclarecer, ficarei agradecido :stuck_out_tongue:

Abraços a todos e obrigado…

11 Respostas

T

Impressão não é prova. Prove a sua afirmação, executando os trechos de código que você postou.

B

Ambos continuam rodando. Não confunda as coisas, você apenas trata a exceção dentro do catch. Lançar uma exceção não é tratar nada.

aleck

No primeiro caso vc está capturando um erro de execução, no segundo vc está repassando este erro para a classe que chamou o método.

MaikoID

Opa agora me veio uma dúvida.

O codigo

throw new NumberFormatException("Erro");

È executado ?

Porque se a exception é lancada no parseInt(x); ele não deveria pular a execução para o tratamento da exception ?

abraço.

T
class TesteTryCatch {
    public static void main(String[] args) {
/*
Imprime o seguinte stack trace:
java.lang.NumberFormatException: For input string: "x"
        at java.lang.NumberFormatException.forInputString(Unknown Source)
        at java.lang.Integer.parseInt(Unknown Source)
        at java.lang.Integer.parseInt(Unknown Source)
        at TesteTryCatch.main(TesteTryCatch.java:13)
*/
try {  
String s = "x";  
int i = Integer.parseInt(s);  
} catch (NumberFormatException e) {  
e.printStackTrace();  
}
/*
Imprime o seguinte stack trace:
java.lang.NumberFormatException: Erro
        at TesteTryCatch.main(TesteTryCatch.java:25)
*/
try {  
String s = "1";  
int i = Integer.parseInt(s);  
throw new NumberFormatException("Erro");  
} catch (NumberFormatException e) {  
e.printStackTrace();  
} 
    }
}

Rodando seu código, você pode ver que a sua afirmação é incorreta.

T

MaikoID:
Opa agora me veio uma dúvida.

O codigo

throw new NumberFormatException("Erro");

È executado ?

Porque se a exception é lancada no parseInt(x); ele não deveria pular a execução para o tratamento da exception ?

abraço.

Conforme você viu no código que você postou, o código será executado porque não houve uma exceção sendo lançada no parseInt (s). (Não há uma variável chamada “x” no seu programa; tomei a liberdade de corrigir).

davidbuzatto
aleck:
No primeiro caso vc está capturando um erro de execução, no segundo vc está repassando este erro para a classe que chamou o método.

Passando para a classe que chamou?

Olhe isso aqui:
public class Teste {

    public static void main( String[] args ) {
    	
    	try {
    		
    		throw new ClassCastException( "exemplo " );
    		
    	} catch ( ClassCastException exc ) {
    		
    		System.out.print( exc.getMessage() );
    		
    		try {
    			
    			throw new NumberFormatException( "de exceções " );
    			
    		} catch ( NumberFormatException excn ) {
    			
    			System.out.print( excn.getMessage() );
    			
    			try {
    				
    				throw new ArrayIndexOutOfBoundsException( "aninhadas" );
    				
    			} catch ( ArrayIndexOutOfBoundsException exca ) {
    				
    				System.out.println( exca.getMessage() );
    				
    			}
    		}
    		
    	}
    	
    }
    
}
O que está acontecendo? :D
vitor_lima
Bem, quando você lança uma exeção fazendo 

         [b] throw new <nomeDaClasseDeExceção>(<argumento> );  [/b]

       é criada uma nova exceção que fica esperando para ser tratada, o que geralmente ocorre
       na classe que chamou o método criador da exceção, mas no seu caso, o primeiro lugar em que ela 
       pode ser tratada é no próprio [b]catch[/b] do seu try/catch.
              Por isso a exceção não é lançada.

              Se você mudar a linha    [b]catch ( ClassCastException exc ) {[/b]
       para por exemplo       [b] catch( NumberFormatException z){ [/b]
       a exceção não será tratada, e portanto, será lançada.

             Coloquei seu código em um método a parte  para demonstrar no 
       método [b]main[/b] o tratamento da exceção lançada.

public class TestaTryCatch {

public static void main(String[] args ) {
    	try{
    		testa();
    	}catch(Exception e){
    		System.out.println("Lançamento funcionou!");
    	}
    	
    }
    
    
    public static void testa(){
    	try {	    		
    		throw new ClassCastException( "exemplo " );
    		
    	} catch ( ArrayIndexOutOfBoundsException exc ) {	    		
    		System.out.print( exc.getMessage() );
    		
    		try {	    			
    			throw new NumberFormatException( "de exceções " );
    			
    		} catch ( NumberFormatException excn ) {	    			
    			System.out.print( excn.getMessage() );
    			
    			try {	    				
    				throw new ArrayIndexOutOfBoundsException( "aninhadas" );
    				
    			} catch ( ArrayIndexOutOfBoundsException exca ) {	    				
    				System.out.println( exca.getMessage() );
    			}
    		}
    	}
   }

}

aleck

Erro meu de interpretação, pensei que o thundercas estava com dúvida no conceito de catch e throw. :oops:

De qualquer forma a dúvida dele já foi muito bem respondida pelo vitor lima.

vitor_lima

Quanto a dúvida do cara com uma foto de um cão jogando CS
(bela foto, muito boa mesmo . . .) ,
o MaikoID

" Opa agora me veio uma dúvida.
O codigo

throw new NumberFormatException("Erro");

È executado ?

Porque se a exception é lancada no parseInt(x); ele não deveria pular a execução para o tratamento da exception ?

abraço"

eu fiz o seguinte teste:

public class TestaTryCatch {

	    public static void main(String[] args ) {
	    	try {
	    	    String s = "X";
	    	    int i = Integer.parseInt(s);
	    	    
	    	    System.out.println("A PRÓXIMA LINHA É: throw new NumberFormatException(\"Erro\"); ");
	    	    throw new NumberFormatException("Erro");
	    	   
	    	} catch (NumberFormatException e) {
	    	 
	    	    System.out.println("VEIO PARA O CATCH");
	    	}
	    }
}
[code]

O System.out.println() que está dentro do try não é executado,portanto
a linha de código que lança a exceção também não é.
A execução vai direto para o catch como você havia observado.

MaikoID

Primeiro nem fui eu postei o código, me confudiram ali em cima.
Segundo vlw pela foto, e isso é um urso, da uma olhada no fucinho aushusahusa!
Terceiro imagina que eu tenha o seguinte codigo

static void metodoDoCaraiQueValidaDrogaNenhuma(int x) throws NumberFormatException{
        if(x < 0){
            throw new NumberFormatException("Numerinho sem vergonha que presta pra porra nenhuma " + x);
        }
        else{
            System.out.println("Isso sim é um numero sangue bão " + x);
        }
    }

    public static void main(String[] args) {
        try {
            metodoDoCaraiQueValidaDrogaNenhuma(1);
            metodoDoCaraiQueValidaDrogaNenhuma(-1);
        } catch (Exception e) {
            System.out.println(e.getLocalizedMessage());
        }
    }

Tem a seguinte saida

run:
Isso sim é um numero sangue bão 1
Numerinho sem vergonha que presta pra porra nenhuma -1
BUILD SUCCESSFUL (total time: 0 seconds)

Digamos eu posso usar as excecoes ao invés de controle por variavel para o controle de fluxo ? Fica muito lento digamos se um método quando dá algum erro de regra de negocio mandar uma exceção ou setar a variável de retorno com -1. e testar com um if depois ?

Exemplificando

static int metodoDoCaraiQueValidaDrogaNenhuma(int x) {
        int retorno;
        if (x < 0) {
            retorno = -1;
        } else {
            System.out.println("Isso sim é um numero sangue bão " + x);
            retorno = x;
        }
        return retorno;
    }

    public static void main(String[] args) {
        int x = 1;
        if (metodoDoCaraiQueValidaDrogaNenhuma(x) < 0) {
            System.out.println("Numerinho sem vergonha que presta pra porra nenhuma " + x);
        }
        x = -1;
        if (metodoDoCaraiQueValidaDrogaNenhuma(x) < 0) {
            System.out.println("Numerinho sem vergonha que presta pra porra nenhuma " + x);
        }

    }

Lógico que é um exmplo ridiculo, mas neste caso é preferivel o primeiro metodo pois fica mais legivel. O que eu não sei é se é sacrificado muito desempenho em comparação aos if’s do segundo.

Abraço.

ps: criando esses metodos eu aprendi que não é preciso ter um throws na declaração do método para a exception ser tratado no método que o chamou rsrs.

Criado 30 de junho de 2009
Ultima resposta 31 de jul. de 2009
Respostas 11
Participantes 7