Exception [resolvido]

22 respostas
Sleipbr

Segundo a apostila Caelum F11, exceção representa uma situação que normalmente não ocorre e representa algo estranho ou inesperado no sistema. Resumindo exceção ocorre diante de um possivel ERRO em java.

Mas também vi lá que sistemas de verdade devem ser tratado o erro diante daquele que chamou o método, então o correto não é tentar corrigir dentro de uma classe. Então isso é exceção?

Pelo que eu vi na apostila esse código abaixo não seria exceção, seria apenas uma forma de tentar corrigir através da classe de (métodos), tendo conhecimento que não é correto, logo que quem deve tratar o erro é que chamou o método que seria um objeto. A classe (método) apenas retornaria um valor para false ou true?

import java.util.Scanner;

public class Conta {

        private double saldo;
        
        Scanner input = new Scanner( System.in ); 

        public double getSaldo() {
                return saldo;
        }

        public void setSaldo(double saldo) {
                this.saldo = saldo;
        }
        
        public double deposita(double valor) {
                saldo+=valor;
                return saldo;
        }
        
        public double setLimite(double valor) {
                while(valor>saldo) {
                   System.out.println("Limite Invalido");
                   valor = input.nextDouble();
                }
                return valor;
        }
        
        public double sacar(double valor) {
                while(valor>saldo) {
                        System.out.println("Não é possivel tirar essa quantia");
                        valor = input.nextDouble();
                }
                return saldo;
        }
}

Através de exceção como ficaria esse código?

22 Respostas

Rodrigo_Sasaki

Você tem que identificar as situações que não estão no seu fluxo “feliz”, rs. (Termos do meu professor da faculdade).

Qualquer coisa que seja inconsistente, um erro, como você mesmo disse.
Nesses lugares podem ser lançadas exceções.

Aonde no seu código as coisas podem dar errado? Aonde o usuário pode ter inserido informações inválidas?

Ficou mais claro?

Não quero dar a resposta pra te dar a chance de chegar nela sozinho.

JuniorMaia

Nos sistema que desenvolvo, utilizo de try/catch, onde try é o comando funcional, e o catch é um erro.

exemplo:

try {
  //comando efetivo funcional
}catch {
  //erro
}
E
public double sacar(double valor) {  
                while(valor>saldo) {  
                        System.out.println("Não é possivel tirar essa quantia");  
                        valor = input.nextDouble();  
                }  
                return saldo;  
        }

O método “sacar” está fazendo mais coisas que ele deveria fazer.

Se você tentar sacar algo mais que o valor do saldo, você tem de tratar esse problema em quem chama esse método “sacar”, não dentro do método “sacar”.

Uma vantagem disso é que você elimina a parte de entrada e saída de dados dessa sua classe que mexe só com contas.

Veja a divisão das responsabilidades… Quando cada um faz a sua parte, e sabe exatamente o que deve ser feito, é mais fácil de você reaproveitar e testar as coisas.

E

Além disso, do jeito que você escreveu seu código, você pode tentar sacar um valor negativo sem problemas - a sua validação está incorreta :slight_smile:

Sleipbr

Fiz o seguinte

criei uma classe Saques que vai herdar de Exception

public class Saques extends Exception {

}

Classe Conta

import java.util.Scanner;

public class Conta {

	private double saldo;
	
	Scanner input = new Scanner( System.in ); 

	public double getSaldo() {
		return saldo;
	}

	public void setSaldo(double saldo) {
		this.saldo = saldo;
	}
	
	public double deposita(double valor) {
		return saldo+=valor;
	}
	
	public double setLimite(double valor) throws Saques {
		if(valor>saldo) {
			throw new Saques();
		}
		return valor;
	}
	
	public double sacar(double valor) throws Saques {
		if(valor>saldo) {
			throw new Saques();
		}
		return (saldo-=valor);
	}
}

Classe Principal

import java.util.Scanner;
public class Principal extends Conta {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		
		Conta minhaConta = new Conta();
		Scanner input = new Scanner( System.in ); 
		boolean continua = true;
		
		do {
			try {
			   minhaConta.deposita(100);
			   minhaConta.setLimite(100);
			   double valor = input.nextDouble();  
			   minhaConta.sacar(valor);
			   continua = false;
			}
			catch(Saques c) {
				System.out.println("ERRO");
			}
		} while(continua);
		

	}

Acho que agora está correto. E ai?

Rodrigo_Sasaki

A idéia básica é essa sim, mas como o entanglement falou, sua validação ainda está errada :slight_smile:

O que ocorre se tentar sacar um valor negativo?

Sleipbr

public double sacar(double valor) throws Saques { if((valor>saldo) || (valor<0)){ throw new Saques(); } return (saldo-=valor); } }

Rodrigo_Sasaki

Sim, mas agora seguem algumas boas práticas (pelo menos na minha opinião):

- Sempre deixe Exception no nome da classe, assim tanto a identificação quanto a busca ficam muito mais fáceis.
- Envie uma descrição breve do erro ao lançá-la, assim sua stackTrace fica mais legível

Ex:
public class SaqueException extends Exception {

	private static final long serialVersionUID = 1L;

	public SaqueException(String error) {
        super(error);
    }

}
Aí na hora de lançar você pode enviar uma descrição breve.
throw new SaqueException("Não é possível sacar valores negativos.");
Sleipbr

valeu!
Outra dúvida, exceções não verificadas são aquelas exceções padrão da JVM, tipo ArithmeticException? E as exceções verificadas são as herdadas por Exception feita pelo desenvolvedor?

(Run Time Exception) -> Não verificadas?
(Herdada de Exception -> Verificadas?

Rodrigo_Sasaki

Checked Exceptions são todas as exceções que não ocorrem em tempo de execução (Runtime).

Exemplo. Em Runtime você pode se deparar com exceções como NullPointerException, que são exceções que não são detectadas em tempo de compilação.

agora as checadas é possível você prever, como uma FileNotFoundException.

Sleipbr

Em que momento devo usar as checked ( acho que:quando for tratar de uma exception que eu mesmo tratei, igual nesse codigo do banco?) e no-checked?

Tem que tomar atenção redobrada nas exception não verificadas, pois elas ocorrem geralmente em tempo de execução, sendo mais perigosa?

Rodrigo_Sasaki

Assim… as checked exceptions você tem que tratar, senão não compila, se estiver usando uma IDE fica aquele sublinhado vermelho que incomoda qualquer um.

Ja as Runtime, você tem que planejar seu código, tratamento e verificação (se necessário) dos parâmetros recebidos em métodos, etc.

Se for lançada uma NullPointerException você vai descobrir rapidinho, rs.

Sleipbr

Saquei

No-Checked

public class Principal {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		Calculadora calc = new Calculadora();
		calc.div(2,0);
	}

}
public class Calculadora {

	public double div(double a,double b){
		return a/b;
	}
}

Checked

public class Principal {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		Calculadora calc = new Calculadora();
		calc.div(a,2);
	}

}
Rodrigo_Sasaki

não… no seu caso (a/2) seria um erro mesmo hehehe… segue um exemplo de checked exception: public static void main(String[] args){ File file = new File("C:\\"); FileReader fileReader = new FileReader(file); }Experimente copiar esse código e ver o que a IDE apresenta.

S

Não confunda erro com exception. Existe uma classe chamada Error e uma chamada Exception.

Sleipbr

Entendi, achei outro:

Mas algumas coisas ainda está um nó pra mim

public class Principal {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		System.out.println(2/0);
	}

}

mas porque seu eu fizer assim ele irá dar resultado Infinity

public class Principal {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		Calculadora calc = new Calculadora();
		System.out.println(calc.div(2,0));
	}

}
public class Calculadora {

	public double div(double a,double b){
		return a/b;
	}
}
Rodrigo_Sasaki

uma divisão por 0 é impossível, mas acho que você ja sabia disso.

Se sua pergunta é “Por que o compilador deixa eu enviar um zero na divisão, sabendo que não é possível dividir por 0?”
é simplesmente porque ele não “sabe”.

ele sabe que tem que receber 2 parâmetros inteiros, e aí dentro do método a história é outra. Você realmente está enviando 2 inteiros, agora o tratamento fica por sua conta.

Sleipbr

Hmmm…entendi, VALEU!

Sleipbr

Vocês estão me ajudando demais...

Por hoje eu só quero tirar mais essa dúvida em relação a exceções...

import java.util.Scanner;

public class Principal {
	
	public static void main(String args[]) {
		
		boolean condicao = true;
		
		do {
		try {
			Scanner entrada = new Scanner( System.in );
			System.out.println("Informe o primeiro numero");
			int num1 = entrada.nextInt();
			System.out.println("Informe o segundo numero");
			int num2 = entrada.nextInt();
			int sum = num1/num2;
			System.out.println(sum);
			condicao=false;
		}
		catch(Exception e) {
			System.out.println("Não é possivel dividir por zero");
		}
		} while(condicao==true);
	}
	
}

nessa exceção, quando alguma coisa irregular no bloco try é encontrado ele para na linha que está irregular (int sum = num1/num2) e não interpreta o resto, depois vai para o bloco do catch, mosta a mensagem e continua o do/while até a correção?

Valeu!!!

Rodrigo_Sasaki

Você experimentou testar? heheeh

Se uma exceção é lançada ele pula direto pro catch sim, e no seu caso, ele continuaria o loop, assim como você disse.

Sleipbr

eu vi nessa video aula http://www.youtube.com/watch?v=K_-3OLkXkzY e implementei, ai imaginei isso que quando a exceção fosse lançada ele pularia para o catch. Agora você me confirmou isso então ficou melhor. :-o Agora tudo está ficando claro. rsrs

Rodrigo_Sasaki

Hehehe, é bom você ter esses fundamentos bem fixos na sua mente, vai te ajudar um bocado la pra frente, tem bastante programador que não sabe tratar uma exceção corretamente.

Criado 10 de maio de 2012
Ultima resposta 11 de mai. de 2012
Respostas 22
Participantes 5