Capturar throw exception!

Boa tarde Pessoal !

Estou com uma dúvida sobre como capturar um throw exception.
Vou exemplificar com uma classe teste e com um unico atributo p/ ficar mais facil O que ocorre é o seguinte:

  • Tenho uma classe Pessoa que tem o atributo Idade;
  • Criei os métodos getters e setters do mesmo;
  • No método set, vou fazer um teste onde verifico se a idade esta entre 20 e 50. Portanto se idade for menor que 20 e maior que 50 estaria errado.
  • Sendo assim, se o usuário digitar a idade 15 e clicar em OK na página, o mesmo irá cair no set e testar. Como 15 é menor que 20, o mesmo entrará no teste e irá gerar um throw exception com a mensagem “Idade inválida.”
  • Só que ao entrar no teste e executar o throw exception, o mesmo muda para a página de erro e mostra que gerou uma exceção com a mensagem “Idade inválida”.
    Minha dúvida: O que quero é capturar essa mensagem e apresentar na frente do campo como uma observação que a data estaria errada, e não mudar para a página de erro.

Alguem tem alguma ideia de como fazer isso ? Estou procurando na net e ainda não consegui achar nada.

Segue abaixo como esta minha classe com o método set.

public class Pessoa {

    private Integer idade;

    //Construtor
    public Pessoa() {
    }

    //Getters e Setters
    public Integer getIdade() {
        return idade;
    }

    public void setIdade(Integer idade){
        if (idade < 20 || idade > 50) {
            throw new Exception("Idade inválida");
        }
        this.idade = idade;
    }
}

Obs.: O exemplo é bem simples realmente para que eu possa explicar a minha dúvida.

Para isso, o método chamador tem que ter um tenta{} gato{} (try{} catch{}). rs

try{
     
     setIdade(10);
     mudaPagina();
}catch(Exception e)
{
      e.printStackTrace();
      mostraMensagem();
}

Parece não ser uma boa prática voce lancar uma exception dentro do método set.
Ao invés disso, voce poderia ter um metodo verificarIdade() que retornaria um boolean.
Não é muito bom ficar usando exception para mostrar mensagens.

Não é uma boa prática vc manipular isso nos métodos get/set.

Eu faria da seguinte forma:

public class Pessoa {

    private Integer idade;

    //Construtor
    public Pessoa() {
    }

    //Getters e Setters
    public Integer getIdade() {
        return idade;
    }

    public void setIdade(Integer idade){
        this.idade = idade;
    }

    public void verificaIdade(Integer idade) throws Exception {
        if (idade < 20 || idade > 50) {
            throw new Exception("Idade inválida");
        }
        else{
            setIdade(idade)
        }        
    }
}

Para o seu método lançar uma exceção, vc tem que declara-la. Como fiz acima com: “throws Exception”

E no seu código vc usaria da seguinte forma;

try{
   Pessoa pessoa = new Pessoa();
   pessoa.verificaIdade(25);
}
catch(Exception e)
{
   e.getMessage();
}

É uma péssima prática lançar uma exception do tipo Exception. Assim como é uma prática pior ainda capturar uma exception do tipo Exception.
Procure lançar uma IllegarArgumentException, ou crie você mesmo sua hierarquia de exceções. Capture os tipos específicos na camada de cima.

Lembre-se catch(Exception e) captura todas as exceções que seu programa lança, seja as que você está esperando, seja as que você não está. Portanto, crie uma hierarquia das que você espera, e gere log mais específicos, e uma tela menos agressiva para o usuário, para as que você nem tinha idéia que poderiam ocorrer.

É melhor do que de repente pipocar uma caixinha na sua aplicação com um erro como: “ArrayIndexOutOfBounds: -1” e seu usuário ver isso.

@Marck, @ViniGodoy

Não entendi porque não é uma boa prática fazer validações nos métodos set? É exatamente o contrário!! Fazendo isso você não tem objetos inválidos passeando pela sua aplicação sob o risco de tomar um persist ainda e ferrar contigo. Podem explicar porque não é boa prática ou mostrar algum lugar que diz isso?

sets podem muito bem atirar exceções, são métodos como quaisquer outros.

Também concordo com o ViniGodoy sobre atirar Exceptions. Atire uma IllegalArgumentException, ou uma subclasse desta no lugar da Exception.

[quote=townray]@Marck, @ViniGodoy

Não entendi porque não é uma boa prática fazer validações nos métodos set? É exatamente o contrário!! Fazendo isso você não tem objetos inválidos passeando pela sua aplicação sob o risco de tomar um persist ainda e ferrar contigo. Podem explicar porque não é boa prática ou mostrar algum lugar que diz isso?[/quote]

Eu não falei que não se deve atirar exceções nos sets.

Falei que não se deve atirar exceções do tipo “Exception” diretamente.

Você deve criar uma subclasse, mais específica. Isso pq um throw Exception pega muito mais exceptions do que se pretendia originalmente (na verdade, ele pega absolutamente todas as exceptions, Runtime ou não).

O Mark também fez uma observação interessante. Geralmente não é uma boa prática usar as próprias exceções para exibir mensagens. Na interface gráfica, você faz os métodos que verificam a entrada, e dá mensagens de erros localizadas, e com um texto mais acessível ao seu usuário, o que é muito mais adequado para a camada de view.

Mas isso também não significa que você vá verificar as condicionais e não disparar exceções no set. Isso você vai continuar fazendo. Só que uma exception, como o nome já diz, deveria representar um comportamento de exceção no seu sistema, não uma regra.