[RESOLVIDO]Dúvida sobre utilização de uma exceção feita por mim mesmo no codigo

10 respostas
J

Boa noite amigos,
Estou com uma dúvida sobre a utilização de uma exceção que criei no meu programa, segue:

public static void utilizarMicroondas(Microondas micro) throws EmUtilizacaoException{
		try{
			if(micro.isUtilizando()){
				throw new EmUtilizacaoException();
			}
			else{
				Scanner ler = new Scanner(System.in);
				micro.porta.abrirPorta(micro, true);
				System.out.println("Coloque o alimento para aquecer e pressione alguma tecla para continuar!");
				String string = ler.nextLine();
				micro.porta.abrirPorta(micro,false);
				micro.setUtilizando(true);
			}
		}
		catch(EmUtilizacaoException emuso){
			System.out.println(emuso.getMessage());
		}	
	}

Quando a exceção é lançada, ele chama o getMessage e depois continua la no else, no meu caso quando o micro.isUtilizando for true nao deveria executar oq está no else.
Pq está executando? Isso é normal?

Valeu pela ajuda!

10 Respostas

DaniloAndrade

Bom dia,

eu não sei dizer por que ta caindo no seu else, mas vou vou fazer uns comentarios no seu codigo

public static void utilizarMicroondas(Microondas micro) throws EmUtilizacaoException{  // pra que dizer que seu metodo pode lançar uma "EmUtilizacaoException" se você esta tratando no "catch"
            try{  
                if(micro.isUtilizando()){  
                    throw new EmUtilizacaoException();  
                  // pra que lançar uma exceçao se vc vai tratar la em baixo no catch, se vc sabe qual a mensagem da sua exception  vc poderia so da o println na mensagem direto 
                  // melhor que lançar uma exceção pra tratar em seguida, mas isso é uma visão minha
                }  
                else{  
                    Scanner ler = new Scanner(System.in);  
                    micro.porta.abrirPorta(micro, true);  
                    System.out.println("Coloque o alimento para aquecer e pressione alguma tecla para continuar!");  
                    String string = ler.nextLine();  
                    micro.porta.abrirPorta(micro,false);  
                    micro.setUtilizando(true);  
                }  
            }  
            catch(EmUtilizacaoException emuso){  
                System.out.println(emuso.getMessage());  
            }     
        }
rmendes08

DaniloAndrade:
Bom dia,

eu não sei dizer por que ta caindo no seu else, mas vou vou fazer uns comentarios no seu codigo

public static void utilizarMicroondas(Microondas micro) throws EmUtilizacaoException{ // pra que dizer que seu metodo pode lançar uma "EmUtilizacaoException" se você esta tratando no "catch" try{ if(micro.isUtilizando()){ throw new EmUtilizacaoException(); // pra que lançar uma exceçao se vc vai tratar la em baixo no catch, se vc sabe qual a mensagem da sua exception vc poderia so da o println na mensagem direto // melhor que lançar uma exceção pra tratar em seguida, mas isso é uma visão minha } else{ Scanner ler = new Scanner(System.in); micro.porta.abrirPorta(micro, true); System.out.println("Coloque o alimento para aquecer e pressione alguma tecla para continuar!"); String string = ler.nextLine(); micro.porta.abrirPorta(micro,false); micro.setUtilizando(true); } } catch(EmUtilizacaoException emuso){ System.out.println(emuso.getMessage()); } }

Danilo, você está certo, não tem sentido lançar uma exceção em um bloco try-catch que capture a exceção.

cogumello

Você pode tentar inverter a chamada do If:

Jo? Paulo Vasconcelos:
Boa noite amigos,

public static void utilizarMicroondas(Microondas micro) {
		try{
			if(!micro.isUtilizando()){
				Scanner ler = new Scanner(System.in);
				micro.porta.abrirPorta(micro, true);
				System.out.println("Coloque o alimento para aquecer e pressione alguma tecla para continuar!");
				String string = ler.nextLine();
				micro.porta.abrirPorta(micro,false);
				micro.setUtilizando(true);	
			}
			else{
				throw new EmUtilizacaoException();
			}
		}
		catch(EmUtilizacaoException emuso){
			System.out.println(emuso.getMessage());
		}	
	}

Quanto às exceções, como vocês já está tratando ela no catch, não precisa fazer o método lançá-la (que aliás nunca seria lançada).

Acho correto o lançamento de uma exceção e seu tratamento em seguida, assim o código fica mais organizado, enfatizando o tratamento de erros. Nesse caso você está dando um simples println, mas se fosse um tratamento mais complexo poderia deixar o código “poluído”.

D

Jo? Paulo Vasconcelos:
Boa noite amigos,
Estou com uma dúvida sobre a utilização de uma exceção que criei no meu programa, segue:

public static void utilizarMicroondas(Microondas micro) throws EmUtilizacaoException{
		try{
			if(micro.isUtilizando()){
				throw new EmUtilizacaoException();
			}
			else{
				Scanner ler = new Scanner(System.in);
				micro.porta.abrirPorta(micro, true);
				System.out.println("Coloque o alimento para aquecer e pressione alguma tecla para continuar!");
				String string = ler.nextLine();
				micro.porta.abrirPorta(micro,false);
				micro.setUtilizando(true);
			}
		}
		catch(EmUtilizacaoException emuso){
			System.out.println(emuso.getMessage());
		}	
	}

Quando a exceção é lançada, ele chama o getMessage e depois continua la no else, no meu caso quando o micro.isUtilizando for true nao deveria executar oq está no else.
Pq está executando? Isso é normal?

Valeu pela ajuda!

throws EmUtilizacaoException você só usa no caso de não tratar a exception no método e irá passar adiante para quem chamou o método que será obrigado a trata-lo
Ex:

class testa{
     public static void main(String args[]){
          try{
               utilizarMicroondas(micro);
          }catch(EmUtilizacaoException e){
               System.out.println(e.getMessage()); 
          }
     }
}

Leia esse artigo, vai ajuda:

J

Boa noite Pessoal,
Muito obrigado a todos que me ajudaram postando nesse tópico, tentei fazer como o djunigari disse, colocando o try catch na chamada do metodo como no exemplo dele:

switch(retorno){
				case 1:
					try{
						Microondas.utilizarMicroondas(micro);
					}
					catch(EmUtilizacaoException emuti){
						System.out.println(emuti.getMessage());
					}
						usartempo = Cronometro.solicitaTempo();
						Cronometro.contador(micro, usartempo);
						break;

Dentro do metodo deveria ficar assim? :

public static void utilizarMicroondas(Microondas micro) throws EmUtilizacaoException{
		
			if(micro.isUtilizando()){
				throw new EmUtilizacaoException();
			}
			else{
				Scanner ler = new Scanner(System.in);
				micro.porta.abrirPorta(micro, true);
				System.out.println("Coloque o alimento para aquecer e pressione alguma tecla para continuar!");
				String string = ler.nextLine();
				micro.porta.abrirPorta(micro,false);
				micro.setUtilizando(true);
			}
	}

Se for dessa forma, meu problema ainda continua, pois queria que quando fosse lançada a EmUtilizacaoException, aparecesse a msg para o usuario informando que o “Primeiro retire o alimento antes de colocar!” e voltasse para o menu, onde é chamado esse metodo, consigo (e devo) fazer isso é realmente com exceções?

Obrigado a todos ai!

G

sempre achei q o resultado seria mesmo.

tipo:

se A = 10 faça
print ‘A igual 10’
se não
print ‘A diferente de 10’

se A <> 10 faça
print ‘A diferente de 10’
se não
print ‘A igual 10’

quer dizer, ainda continua achando.

mas ta certo.

esses dias vi um colega falando q tava fazendo isso:

Botao.SetWidth(60);//não tava funcionando.

sugestão.

Botao.SetWidth(060);//será q agora vai?

sergiotaborda

Jo? Paulo Vasconcelos:
Boa noite Pessoal,
Muito obrigado a todos que me ajudaram postando nesse tópico, tentei fazer como o djunigari disse, colocando o try catch na chamada do metodo como no exemplo dele:

switch(retorno){
				case 1:
					try{
						Microondas.utilizarMicroondas(micro);
					}
					catch(EmUtilizacaoException emuti){
						System.out.println(emuti.getMessage());
					}
						usartempo = Cronometro.solicitaTempo();
						Cronometro.contador(micro, usartempo);
						break;

Dentro do metodo deveria ficar assim? :

public static void utilizarMicroondas(Microondas micro) throws EmUtilizacaoException{
		
			if(micro.isUtilizando()){
				throw new EmUtilizacaoException();
			}
			else{
				Scanner ler = new Scanner(System.in);
				micro.porta.abrirPorta(micro, true);
				System.out.println("Coloque o alimento para aquecer e pressione alguma tecla para continuar!");
				String string = ler.nextLine();
				micro.porta.abrirPorta(micro,false);
				micro.setUtilizando(true);
			}
	}

Se for dessa forma, meu problema ainda continua, pois queria que quando fosse lançada a EmUtilizacaoException, aparecesse a msg para o usuario informando que o “Primeiro retire o alimento antes de colocar!” e voltasse para o menu, onde é chamado esse metodo, consigo (e devo) fazer isso é realmente com exceções?

Obrigado a todos ai!

A primeira coisa que salta a vista aqui é a complexidade desnecessária do seu código. Em que classe está aquele switch ? Porque usar método estático ?

Já referiram aqui algumas boas práticas de exceções, mas está faltando referir a principal : não use exceções para controlar fluxo. Exceção, como o nome indica serve para lidar com coisas que vc não espera. Tudo o que vc espera, não é uma exceção.

Depois ha a questão da composição O cronometro é uma peça do microondas, porque o uso do objeto cronometro não é feito de dentro do objeto microondas ? Por outro lado vc abre a porta do microondas (micro.abrePorta) e não abre a porta da porta … coisas simples deste tanto influenciam a compreensão do código, e a compreensão do codigo influencia a escrita e o design. ( micro.porta.abrirPorta(micro,false) denota falta de design )

O que vc quer aqui ?controlar o uso do microondas. Ok.

micro.abrePorta()
// coloca-se o alimento
micro.recebeAlimento(alimento)
// fecha a porta
micro.fechaPorta()
micro.setCronometro(Minutos.valueOf(12)); 
micro.setListener(new MicroondasListener(){
  
         public onTerminado(){
                  micro.abrePorta();
                  Alimento alimento micro.retiraAlimento();
                  //serve alimeto

                 servico.serve(alimento);
         }

});
micro.liga();

Esta é a estrutura básica. Um conjunto de encadeamentos sequenciais de instruções. O que pode dar errado ? Várias coisas. Abrir a porta quando ela já está aberta , receber alimento com a porta fechada (!), ligar sem alimento lá dentro , ligar sem setar o cronometro, etc… Para algumas coisas vc tem como tratar , por exemplo se ligar sem cronometro, set automaticamente 0.5 minutos. Mas e se liga sem alimento ? Catástrofe! É aqui que entram as exceções. Exceções são maus usos do microondas. Saber se o micro está ligado não é uma exceção. então eis o que fariamos

try {

   // todo aquele código de antes
   ...

} catch (MauUsoException e) {

   System.out.println( "Mau uso do microondas. Leia o manual antes de usar. O uso indevido pode levar à morte");

}

as verificações seriam feitas em cada método por exemplo

public void liga(){

    if (this.balanca.getPeso() <  0 ){
            throw new MauUsoException("Não é possível ligar sem alimento");
   }

}

Veja que estou usando um outro componente do microondas que é a balança para verificar se existe alimento. O controle da porta não é suficiente.

em relação à classe de exceção em si é só fazer

public class MauUsoException extends RuntimeException {

}

Mas acho que essa parte vc já sabia

J

sergiotaborda:
Jo? Paulo Vasconcelos:
Boa noite Pessoal,
Muito obrigado a todos que me ajudaram postando nesse tópico, tentei fazer como o djunigari disse, colocando o try catch na chamada do metodo como no exemplo dele:

switch(retorno){
				case 1:
					try{
						Microondas.utilizarMicroondas(micro);
					}
					catch(EmUtilizacaoException emuti){
						System.out.println(emuti.getMessage());
					}
						usartempo = Cronometro.solicitaTempo();
						Cronometro.contador(micro, usartempo);
						break;

Dentro do metodo deveria ficar assim? :

public static void utilizarMicroondas(Microondas micro) throws EmUtilizacaoException{
		
			if(micro.isUtilizando()){
				throw new EmUtilizacaoException();
			}
			else{
				Scanner ler = new Scanner(System.in);
				micro.porta.abrirPorta(micro, true);
				System.out.println("Coloque o alimento para aquecer e pressione alguma tecla para continuar!");
				String string = ler.nextLine();
				micro.porta.abrirPorta(micro,false);
				micro.setUtilizando(true);
			}
	}

Se for dessa forma, meu problema ainda continua, pois queria que quando fosse lançada a EmUtilizacaoException, aparecesse a msg para o usuario informando que o “Primeiro retire o alimento antes de colocar!” e voltasse para o menu, onde é chamado esse metodo, consigo (e devo) fazer isso é realmente com exceções?

Obrigado a todos ai!

A primeira coisa que salta a vista aqui é a complexidade desnecessária do seu código. Em que classe está aquele switch ? Porque usar método estático ?

Já referiram aqui algumas boas práticas de exceções, mas está faltando referir a principal : não use exceções para controlar fluxo. Exceção, como o nome indica serve para lidar com coisas que vc não espera. Tudo o que vc espera, não é uma exceção.

Depois ha a questão da composição O cronometro é uma peça do microondas, porque o uso do objeto cronometro não é feito de dentro do objeto microondas ? Por outro lado vc abre a porta do microondas (micro.abrePorta) e não abre a porta da porta … coisas simples deste tanto influenciam a compreensão do código, e a compreensão do codigo influencia a escrita e o design. ( micro.porta.abrirPorta(micro,false) denota falta de design )

O que vc quer aqui ?controlar o uso do microondas. Ok.

micro.abrePorta()
// coloca-se o alimento
micro.recebeAlimento(alimento)
// fecha a porta
micro.fechaPorta()
micro.setCronometro(Minutos.valueOf(12)); 
micro.setListener(new MicroondasListener(){
  
         public onTerminado(){
                  micro.abrePorta();
                  Alimento alimento micro.retiraAlimento();
                  //serve alimeto

                 servico.serve(alimento);
         }

});
micro.liga();

Esta é a estrutura básica. Um conjunto de encadeamentos sequenciais de instruções. O que pode dar errado ? Várias coisas. Abrir a porta quando ela já está aberta , receber alimento com a porta fechada (!), ligar sem alimento lá dentro , ligar sem setar o cronometro, etc… Para algumas coisas vc tem como tratar , por exemplo se ligar sem cronometro, set automaticamente 0.5 minutos. Mas e se liga sem alimento ? Catástrofe! É aqui que entram as exceções. Exceções são maus usos do microondas. Saber se o micro está ligado não é uma exceção. então eis o que fariamos

try {

   // todo aquele código de antes
   ...

} catch (MauUsoException e) {

   System.out.println( "Mau uso do microondas. Leia o manual antes de usar. O uso indevido pode levar à morte");

}

as verificações seriam feitas em cada método por exemplo

public void liga(){

    if (this.balanca.getPeso() <  0 ){
            throw new MauUsoException("Não é possível ligar sem alimento");
   }

}

Veja que estou usando um outro componente do microondas que é a balança para verificar se existe alimento. O controle da porta não é suficiente.

em relação à classe de exceção em si é só fazer

public class MauUsoException extends RuntimeException {

}

Mas acho que essa parte vc já sabia

Bom dia, Sergio muito obrigado pelo auxílio!
Quando vc diz sobre o design, que fica estranho usar micro.porta.abrirPorta(micro,false); o correto seria criar o metodo abrir porta la dentro do microondas mesmo?
Não separando as “peças” por classes?
Eu pensei que dessa forma, separando todas as “peças” do microondas em classes, ficaria mais fácil para uma futura manutenção.

Outra dúvida, é sobre o uso das exceções, eu ja tinha lido aquele blog q vc me passou, li novamente… e ainda continuo com muitas dúvidas, segue um exemplo:
O usuario deve digitar minutos e segundos para o preparo do alimento.
Caso o usuario digitar um valor negativo para o tempo, seria um mau uso do microondas certo?
Nesse caso eu queria q o programa, corrigisse o valor (multiplicando por -1) e avisasse o usuário que o valor nao pode ser negativo e por isso foi corrigido para o valor positivo.
Eu posso fazer isso com exceções ou nao devo utilizar excecões pra isso?

Valeu pela paciência cmg galera!
:slight_smile: :smiley:

sergiotaborda

Você pode e deve separa as peças. Você tem a porta, a balança, o cronometro, etc… Outras história é você deixar essas peças publicas.
Se A é composto por B e C, isso não significa que B e C são publicos.

A regra é evitar chamadas telescopicas. Ou seja, a.b.c.d(). Isto significa que o publico sabe demais sobre a estrutura do objeto , o que significa mau encapsulamento. Entao vc cria um método micro.abrePorta que por baixo dos panos chama this.porta.abre().

Portanto, o ponto aqui não é a separação, é a visibilidade das peças.

Mais ou menos. Se o microondas permite digitar numeros negativos ( o que é muito estranho) então e´porque ele espera o uso de numeros negativos. Se ele não espera o uso de numeros negativos ele poibe o seu uso. Ou seja, se fosse um campo de texto vc não deixa o usuário digitar o caracter ‘-’ apenas digitos. Com este tipo de design vc não precisa sequer verificar nada nem levantar exceções. Vc simplesmente poibe o usuário de errar.

Mas imaginemos que o usuário sim pode usar o sinal de menos.

Não. Se vc detecta que o numero é negativo e o transforma em positivo vc já resolveu o problema. Não ha exceção aqui pois vc inventou uma regra para contornar o problema.

Vc precisa diferenciar “validação” de “exceção”. Validar significa verificar se certas regras são obdecidas. Quando elas não são vc avisa o usuário. Isto é fluxo normal de qq aplicação. Não é exceção. Tecnicamente vc pode precisar criar classes como ValidationException , mas isto é um artificio tecnico para fazer o “bubble-out” da mensagem de volta para o usuário em certas arquiteturas. Em swing, por exemplo, não precisa usar exceptions.

Exceções são para coisas que vc assumiu que funcionariam. Por exemplo , vc assume que existe um sistema de arquivos quando usa File ou streams, assume que existe um banco de dados que está funcionando, assume que a JVM tem memória suficiente, assume que o relogio da sua máquina sempre anda para a frente ,etc… quando as suas assunções não forem verdadeiras exceções serão lançadas. É por isto que ha as exceções verificadas.
Depois temos as exceções de negocio. mandar tirar dinheiro de uma conta de um cliente quando ela sequer existe, por exemplo ( account é null).

Se vc pode pensar e vc pode resolver e vc pode validar, então não é uma exceção. Só é exceção quando vc não tiver o que fazer. ( por exemplo, ligar o forno sem comida. Vc sabe que é errado e tentará desenhar o micro para isso não aconteça, mas se e quando acontecer, vc não tem como resolver, ai entra a exceção)

J

Hum, acho que agora entendi, chegando em casa vou trabalhar nisso!

Valeu sergio e cia ai!

Criado 22 de julho de 2012
Ultima resposta 25 de jul. de 2012
Respostas 10
Participantes 7