2
respostas

Como tratar exceção em um construtor?

Como posso tratar exceções que podem ser geradas dentro de um construtor quando instanciado?

Por exemplo:

try{
    Conta conta = new Conta(double limite, double valor); //1000, 5000
}catch(Exception e){
    System.out.println(e.getMessage());
}

Se o limite < valor então ele não pode ser instanciado, tem que retornar a exceção.

Caso ele seja instanciado sem exceções, eu não conseguirei utilizar o objeto instanciado pois ele morre logo no final do try.

Como posso tratar exceções desse tipo?

2 respostas

Oi João, tudo bem?

Nesse caso, uma opção seria por toda a lógica que precisa usar a variável conta dentro do try:

try {
    Conta conta = new Conta(double limite, double valor); //1000, 5000

    // todo o código que precisa da variável conta aqui
} catch(Exception e) {
    System.out.println(e.getMessage());
}

Pois assim, caso ocorra exception na linha da criação do objeto, todo o código abaixo que depende da conta criada e válida não será executado. :)

Faz sentido?

Abraço!

Fala João, tudo bem ?

Imagino que seu construtor de Conta deva estar mais ou menos assim:

public class Conta {
    private double limite;
    private double saldo;
    // ...

    public Conta(double limite, double saldoInicial) {
        this.saldo = saldoInicial;

        if (limite < this.saldo) {
            throw new IllegalArgumentException("O limite não pode ser menor que o saldo.");
        } else {
            this.limite = limite;
        }
    }
}

Nesse caso você poderia tratar com um código bem próximo do que você escreveu. O problema ali é que o escopo da variável referência conta fica preso ao try, não permitindo seu uso fora. A primeira vista poderia fazer isso:

public class MainClass {
    public static void main(String[] args) {

        Conta conta = null;
        try {
            conta = new Conta(1000, 5000); // limite menor
        } catch (IllegalArgumentException e) {
            System.out.println(e.getMessage());
        }

    // o que fazer depois ? como prossegue ?
        // quais operações são chamadas depois
    }
}

Assim você ainda teria a variável fora do try. Mas isso pode levar a um problema maior. Quando tudo der certo você terá o objeto referenciado pela variável conta, mas quando der a exception seu código prossegue a execução com a variável conta nula. (O que vai ser NullPointerException na certa).

Aí o que fazer ? Tratar possível NullPointerException depois ? Jamais!

Perceba que pro resto do processamento da sua applicação você provavelmente vai precisar da conta instanciada (senão não rola o resto das operações). Ao mesmo tempo não quer ela instanciada com os valores errados.

Nesse caso o melhor a fazer é lançar a exception no construtor e não tratar fora (Só funciona com exceptions filhas de RuntimeException - não checadas - como a IllegalArgumentException). Exemplo:

public class MainClass {
    public static void main(String[] args) {

        Conta conta = new Conta(1000, 5000); // limite menor
       ... 
        conta.saca(200);
        // segue a vida
    }
}

Se tudo der certo, deu certo :) ... Mas e se der errado (como no exemplo acima vai dar errado), a aplicação para, não prossegue com risco de NullPointer, nem dados inválidos e você como desenvolvedor consegue verificar os logs de exception no console, e corrigir o problema.

Você poderia pegar essa questão implementando testes automatizados, ou mesmo tentando manualmente antes de chegar ao fim da funcionalidade que estiver escrevendo.

Enfim, espero ter ajudado no pensamento.

Abraço!