Desafio Java
Sistema bancário com múltiplas exceções e finally
Enunciado
Implemente um sistema bancário simples com operações de depósito e saque. Crie duas exceções personalizadas: SaldoInsuficienteException (checked) e ValorInvalidoException (unchecked). O método sacar deve lançar SaldoInsuficienteException se o valor for maior que o saldo, e ValorInvalidoException se o valor for negativo ou zero. O método depositar deve lançar ValorInvalidoException para valores não positivos. No main, realize uma sequência de operações e use try/catch/finally para tratar erros e exibir o saldo final.
Requisitos
SaldoInsuficienteExceptiondeve ser checked eValorInvalidoExceptionunchecked.- O método
sacardeve lançar as duas exceções conforme as condições. - O método
depositardeve lançarValorInvalidoExceptionpara valores <= 0. - O bloco
finallydeve exibir o saldo final após cada operação.
Código inicial
// Defina as exceções personalizadas aqui
public class Banco {
private double saldo;
public Banco(double saldoInicial) {
this.saldo = saldoInicial;
}
public void sacar(double valor) /* throws ... */ {
// TODO: valide e lance exceções
}
public void depositar(double valor) {
// TODO: valide e lance exceção
}
public double getSaldo() {
return saldo;
}
public static void main(String[] args) {
Banco conta = new Banco(100.0);
// TODO: realize operações e trate exceções
}
}
Saída esperada
Depósito de 50.0 realizado. Saldo: 150.0
Saque de 200.0 falhou: Saldo insuficiente
Saque de -10.0 falhou: Valor inválido
Depósito de -5.0 falhou: Valor inválido
Saldo final: 150.0
Ver dica
No main, chame os métodos dentro de blocos try separados. Use finally para imprimir o saldo após cada operação. Lembre-se de que ValorInvalidoException é unchecked, então não precisa declarar throws para ela.
Mostrar solução
class SaldoInsuficienteException extends Exception {
public SaldoInsuficienteException(String mensagem) {
super(mensagem);
}
}
class ValorInvalidoException extends RuntimeException {
public ValorInvalidoException(String mensagem) {
super(mensagem);
}
}
public class Banco {
private double saldo;
public Banco(double saldoInicial) {
this.saldo = saldoInicial;
}
public void sacar(double valor) throws SaldoInsuficienteException {
if (valor <= 0) {
throw new ValorInvalidoException("Valor inválido");
}
if (valor > saldo) {
throw new SaldoInsuficienteException("Saldo insuficiente");
}
saldo -= valor;
}
public void depositar(double valor) {
if (valor <= 0) {
throw new ValorInvalidoException("Valor inválido");
}
saldo += valor;
}
public double getSaldo() {
return saldo;
}
public static void main(String[] args) {
Banco conta = new Banco(100.0);
try {
conta.depositar(50.0);
System.out.println("Depósito de 50.0 realizado. Saldo: " + conta.getSaldo());
} catch (ValorInvalidoException e) {
System.out.println("Depósito falhou: " + e.getMessage());
} finally {
System.out.println("Saldo atual: " + conta.getSaldo());
}
try {
conta.sacar(200.0);
System.out.println("Saque de 200.0 realizado. Saldo: " + conta.getSaldo());
} catch (SaldoInsuficienteException e) {
System.out.println("Saque de 200.0 falhou: " + e.getMessage());
} catch (ValorInvalidoException e) {
System.out.println("Saque de 200.0 falhou: " + e.getMessage());
} finally {
System.out.println("Saldo atual: " + conta.getSaldo());
}
try {
conta.sacar(-10.0);
System.out.println("Saque de -10.0 realizado. Saldo: " + conta.getSaldo());
} catch (SaldoInsuficienteException e) {
System.out.println("Saque de -10.0 falhou: " + e.getMessage());
} catch (ValorInvalidoException e) {
System.out.println("Saque de -10.0 falhou: " + e.getMessage());
} finally {
System.out.println("Saldo atual: " + conta.getSaldo());
}
try {
conta.depositar(-5.0);
System.out.println("Depósito de -5.0 realizado. Saldo: " + conta.getSaldo());
} catch (ValorInvalidoException e) {
System.out.println("Depósito de -5.0 falhou: " + e.getMessage());
} finally {
System.out.println("Saldo atual: " + conta.getSaldo());
}
System.out.println("Saldo final: " + conta.getSaldo());
}
}
Passo a passo
- Definimos
SaldoInsuficienteExceptioncomo checked (estendeException). - Definimos
ValorInvalidoExceptioncomo unchecked (estendeRuntimeException). - A classe
Bancotem um atributosaldoe métodossacar,depositaregetSaldo. - No
sacar, verificamos se o valor é <= 0 e lançamosValorInvalidoException(unchecked). - Se o valor for maior que o saldo, lançamos
SaldoInsuficienteException(checked). - No
depositar, apenas verificamos valor <= 0 e lançamosValorInvalidoException. - No
main, realizamos quatro operações, cada uma em um blocotry/catch/finally. - O
finallyimprime o saldo atual após cada tentativa, independentemente de erro.
Por que funciona
O uso combinado de exceções checked e unchecked permite diferenciar erros recuperáveis (saldo insuficiente) de erros de programação (valor inválido). O finally garante que o saldo seja sempre exibido, mantendo o usuário informado. A captura específica de cada exceção permite mensagens de erro precisas.
Erros comuns
- Não declarar
throws SaldoInsuficienteExceptionno métodosacar: erro de compilação, pois é checked. - Lançar
ValorInvalidoExceptionsem capturar: como é unchecked, o programa compila, mas se não for capturada, a exceção sobe e pode encerrar o programa. - Esquecer o
finally: o saldo não seria exibido após cada operação, contrariando o requisito. - Ordem errada dos
catch: capturarExceptionantes deSaldoInsuficienteExceptioncausaria erro de compilação (exceção já capturada).
Outra forma de resolver
Você pode usar um único bloco try com múltiplos catch para todas as operações, mas isso dificultaria identificar qual operação falhou. A abordagem separada é mais clara.
Saída esperada
Depósito de 50.0 realizado. Saldo: 150.0
Saldo atual: 150.0
Saque de 200.0 falhou: Saldo insuficiente
Saldo atual: 150.0
Saque de -10.0 falhou: Valor inválido
Saldo atual: 150.0
Depósito de -5.0 falhou: Valor inválido
Saldo atual: 150.0
Saldo final: 150.0