Exception [resolvido]

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?

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

}
[/code]

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

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.

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

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:

Fiz o seguinte

criei uma classe Saques que vai herdar de Exception

[code]public class Saques extends Exception {

}
[/code]

Classe Conta

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

}[/code]

Classe Principal

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

}[/code]

Acho que agora está correto. E ai?

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?

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

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:[code]public class SaqueException extends Exception {

private static final long serialVersionUID = 1L;

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

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

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?

[quote](Run Time Exception) -> Não verificadas?
(Herdada de Exception -> Verificadas?[/quote]

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.

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?

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.

Saquei

No-Checked

[code]public class Principal {

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

}[/code]

[code]public class Calculadora {

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

}[/code]

Checked

[code]public class Principal {

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

}[/code]

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.

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

Entendi, achei outro:

Mas algumas coisas ainda está um nó pra mim

[code]public class Principal {

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

}
[/code]

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

[code]
public class Principal {

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

}[/code]

[code]public class Calculadora {

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

}[/code]

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.

Hmmm…entendi, VALEU!

Vocês estão me ajudando demais…

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

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

}[/code]

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!!!