[RESOLVIDO] - Tratamento de exceção

4 respostas
ECO2004

O meu programa abaixo roda normalmente, mas o que é impresso divergiu duas vezes.

Ele imprime INICIO, na main e depois entra no método f().
No método, uma exceção é lançada.
Na main, essa exceção é capturada.
Depois, imprime FIM.

A divergência ocorre na impressão do rastreamento da pilha…

A primeira vez que rodei, imprimiu INICIO, o rastreamento da pilha e depois FIM.
Na segunda, imprimiu INICIO, FIM para só depois imprimir o rastreamento da pilha.

Não deveria sempre ocorrer INICIO, pilha e FIM?

Agradeceria uma ajuda!!

package com.wilson.excecao;

public class EX_modificado 
{
	public static void f() throws Exception
	{
		throw new RuntimeException("Não implementado");
	}
	
	public static void main(String []args)
	{
		System.out.println("INICIO");
		
		try
		{
			f();
		}
		
		catch(Exception e)
		{
			e.printStackTrace();
		}
		
		System.out.println("FIM");
	}

}

4 Respostas

ViniGodoy

O que ocorre é que você está imprimindo em dois streams diferentes. O printStackTrace imprime no System.err, que é a saída de erros do processo, e os textos estão imprimindo no System.out, que é a saída padrão.
Apesar dos textos estarem sendo enviados para esses streams na ordem correta, o java não garante a quando que os dados dos streams serão impressos, pois há o controle de coisas como buffers e prioridades para do próprio SO.

Se quiser ver seu programa rodar sempre da mesma forma, jogue tudo para o System.err, ou para o System.out:
package com.wilson.excecao;

public class EX_modificado {
	public static void f() throws Exception {
		throw new RuntimeException("Não implementado");
	}
	
	public static void main(String []args) {
		System.err.println("INICIO");		
		try {
			f();
		} catch(Exception e) {
			e.printStackTrace();
		}
		
		System.err.println("FIM");
	}
}
ECO2004
ViniGodoy:
O que ocorre é que você está imprimindo em dois streams diferentes. O printStackTrace imprime no System.err, que é a saída de erros do processo, e os textos estão imprimindo no System.out, que é a saída padrão. Apesar dos textos estarem sendo enviados para esses streams na ordem correta, o java não garante a quando que os dados dos streams serão impressos, pois há o controle de coisas como buffers e prioridades para do próprio SO. Se quiser ver seu programa rodar sempre da mesma forma, jogue tudo para o System.err, ou para o System.out:
package com.wilson.excecao;

public class EX_modificado {
	public static void f() throws Exception {
		throw new RuntimeException("Não implementado");
	}
	
	public static void main(String []args) {
		System.err.println("INICIO");		
		try {
			f();
		} catch(Exception e) {
			e.printStackTrace();
		}
		
		System.err.println("FIM");
	}
}

Olá, Vini...

Como eu passaria o printStackTrace() para out, já que o padrão é err ?
Outra coisa...tem algum problema em usar err ao invés de out?

ViniGodoy
e.printStackTrace(System.out);

Por padrão, o ideal é jogar a saída comum no out, e erros no err.
Problema em si não tem. Mas por exemplo, se sua aplicação roda num servidor, um administrador de rede pode querer disparar seu programa através de outro, que fique monitorando o System.err e gere logs automáticos, caso sua aplicação dê problemas.

ECO2004

ViniGodoy:
e.printStackTrace(System.out);

Por padrão, o ideal é jogar a saída comum no out, e erros no err.
Problema em si não tem. Mas por exemplo, se sua aplicação roda num servidor, um administrador de rede pode querer disparar seu programa através de outro, que fique monitorando o System.err e gere logs automáticos, caso sua aplicação dê problemas.

Entendi…

O método printStackTrace() recebe um objeto do tipo PrintWriter ou PrintStream e o usa como saída.
Como out é um objeto PrintStream, tudo Ok!

Obrigado pelas dicas!!!

Criado 6 de agosto de 2011
Ultima resposta 6 de ago. de 2011
Respostas 4
Participantes 2