Dúvida Interessante - throw

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…

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

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.

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.

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.

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.

[quote=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.[/quote]

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).

Passando para a classe que chamou?

Olhe isso aqui:

[code]
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() );
				
			}
		}
		
	}
	
}

}[/code]
O que está acontecendo? :smiley:

       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 só 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() );
    			}
    		}
    	}
   }

}

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.

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

[b]" 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"
[/b]

eu fiz o seguinte teste:

[code]

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][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.

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.