Exceptions

7 respostas
B

Pessoal,
depois de estudar bastante sobre as exceções no Java, fiz uns exemplos de códigos pra entender e fiquei com uma dúvida.
Criei uma classe de Teste, na qual tem um método main que chama o metodo estático 1, que por sua vez, chama o método estático 2:

public class TesteErro {
	public static void main(String[] args) {
		System.out.println("Início de main.");
		
		metodo1();
		
		System.out.println("Fim de main.");
	}

	static void metodo1() {
		System.out.println("Início de m1.");
		
		metodo2();
		
		System.out.println("Fim de m1.");
	}

	static void metodo2(){
		System.out.println("Início de m2.");
		int[] array = new int[10];
		try {
			for (int i=1; i<=15;i++){
				array[i]=i;
				System.out.println(i);
			}
		} catch (ArrayIndexOutOfBoundsException e) {
			System.out.println("O Erro foi: "+e);
		}
		System.out.println("Fim de m2.");
	}
}

OBS: no metodo2, é criado um array de 10 possicoes, porém eu insiro 15.
Desta forma, coloquei um try catch pra tratar esse erro. Então quando ele ocorre, o processamento continua normal, e chega a gerar a mensagem de fim do método2.

Mas não entendi o que ocorre com o Throws, pois ouvi falar q ele "empurra" o erro pro método que o chamou.
Daí eu coloquei um theows ArrayIndexOutOfBoundsException no método2 e o try catch eu tratei no método1.
Porém no resultado, não aparece a mensagem de fim do método 2. E mesmo qdo eu coloco o try catch só no método1 e não ponho o throws no metodo2, o sistema mostra o erro da mesma forma.

Pensei que o throws jogava o erro para o método que o chamou, porém não interrompia o processamento (gerando a msg de término do metodo2). Mas mesmo qdo não coloco o throws e ponho o try no metodo que chama, esse método encontra o erro...

Alguém pode me falar o que aconteceu neste caso e tentar clarear minha mente qto a real função do throws e qdo devo usá-lo?

muito obrigado

7 Respostas

Reilander

O que você disse sobre empurrar a exceção para o método que o chamou está correto.
Isso significa que, se no método não houver nenhum tratamento com try-catch, no momento exato que ocorrer a exceção ela será lançada e o método é interrompido automaticamente, equivalendo a um return. Ou seja, o método é interrompido sim!

No entanto, se seu objetivo é que o código lance a exceção mas que mesmo assim execute algum código em particular você faz assim:

static void metodo2() throws ArrayIndexOutOfBoundsException { 
   System.out.println("Início de m2.");  
   int[] array = new int[10];  
   try {  
      for (int i=1; i<=15;i++) {  
         array[i]=i;  // quando chegar no i = 10 vai lançar a exceção
         System.out.println(i);  
      }  
   } 
   finally {  
       // esse código vai ser executado mesmo o código acima lançando uma exceção.
       // se houvesse alguma chamada a return, ele também executaria antes de sair.
       // a única exceção é se a jvm for fechada, como "System.exit(0);"
       System.out.println("Fim de m2."); 
    }
}
B

ótima explicação Reilander…

porém eu queria entender como funciona essa questão de jogar o erro para o método que o chamou…
pois, msm não colocando o throws ArrayIndexOutOfBoundsException e colocando o try/catch no método1, o metodo1 mostra a msg de erro…

eu pensei que só era possível o método1 encontrar o erro(por meio de try/catch) do método2, se o throws estivesse no metodo2, que é o local real da falha…

apesar da boa explicação, fiquei com essas interrogações

Reilander

Nesse caso específico não é preciso o throws, porque essa exeção não é checada, isto é, uma exceção que ocorre em tempo de execução geralmente por erro de programação (nesse caso o range maior que o esperado) ou por alguma falha no sistema que não seria possível quem chamou o método tratar essa exceção.

O que aconteceu é que a exceção não checada foi lançada e como ela estende de Exception, que é o tratamento que você dá no método 1, ela pára ali e o erro é mostrado.

Com ou sem throws, é como se todos os métodos que criamos implicitamente lançasse todas as exceções não checadas da API do Java ou nossas.

NullPointerException é um exemplo de exceção não checada. É como se em todo acesso a um membro de um objeto fosse feito esse teste antes de tentar acessá-lo com o ponto.
Exemplo, se no meu código eu tenho:

String nome = pessoa.getNome();

ao compilar ele seria traduzido para:

if (pessoa == null) {
   throws new NullPointerException();
}
String nome = pessoa.getNome();
J

opa,

o throw lança explicitamente um exceção. Vc pode usá-lo assim (mesmo que NÃO seja o ideal nesta situação):

try {
   for  (int i = 0; i < 15; i++) 
      if (i == 5) throw new arrayIndexOutOfBoundsException; //qdo o valor de  i = 5, uma exceção será lançada
      else array[i] = i;
   } catch (arrayIndexOutOfBoundsException e) {
      System.out.println(e);
   }

A cláusula throws diz que um método pode disparar um exceção. Por exemplo:

public void lancarExcecao() throws arrayIndexOutOfBoundsException {
        for  (int i = 0; i < 15; i++) 
          array[i] = i;

Na chamada do método lancarExcecao(), você deve usar o try/catch:

try { lancarExcecao(); } 
    catch(arrayIndexOutOfBoundsException e) { System.out.println(e); }

Quando você usa a clausula throws, o compilador obriga vc a usar o try/catch na chamada do método.

Espero ter ajudado!

Abraço!!!

B
Com estas explicações,

Entendi que existem as exceções não checadas (unchecked) e checadas pelo compilador (checked)

as exceções checadas devem ser tratadas, ou informando que ela pode ocorrer e mandando o chamador do método tratá-la por try/catch (colocando throws) ou sendo tratado no próprio método (por try/catch)

ainda existem o throw para lançar exceções específicas

Espero ter aprendido corretamente e muito obrigado pessoal…

abraços

OBS: se coloquei algo incorreto, favor me corrijam.

Reilander

Sim, aprendeu correto.

renatocustodio

Um detalhe é que se vc quiser criar sua própria exceção não checada, é só criar uma classe que herda de RunTimeException.

Criado 4 de janeiro de 2009
Ultima resposta 5 de jan. de 2009
Respostas 7
Participantes 4