Dúvida com minha própria exception

7 respostas
Andre_Brito

Galera, estou estudando Exceptions e quero fazer uma exceção verificada, que se o usuário passar como parâmetro um número menor que 10 de erro.

Só que não sei como fazer isso… :frowning: com minha exception. Eu não sei onde devo fazer a verificação (se é menor que 10).

Minha exceção:

/**
 * Excecao Verificada.
 * Herda da Exception
 */

public class MinhaException extends Exception
{

    int numero;

    public MinhaException(int novo)
    {
        super( );
        numero = novo;
    }
    
    public boolean eValido()
    {
        if (numero < 10)
            return false;
        else
            return true;
    }
    
    public String toString()
    {
        if (eValido() == false)
            return "Algo deu errado.\n";
       
        return "";
    }
}

Minha classe que usa a minha exceção:

public class ExemploMinhaExcecao
{
    int numero;

    public ExemploMinhaExcecao(int novo)
    {
        try {
            numero = novo;
            System.out.println("Sucesso.\n");
            throw new MinhaException(novo); // ou seria throws new MinhaException(novo); ?
        }
        catch (MinhaException e) {
            e.toString();
        }
    }
    
    
}

Isso está certo?? Sempre aparece na tela “Sucesso.”… quem sabe se eu lançasse a exceção antes do throw, mas dá erro de compilação :confused:

Só para acrescentar, eu gostaria somente de ficar entre o try e o catch (não quero usar finally).

Acredito que não estou entendendo muito bem exceções.

E deve ser uma exceção verificada ou não verificada???

7 Respostas

peczenyj

A sua exception não deveria ter a responsabilidade de validar esse 'numero'.

Faria mais sentido assim

class MaiorQueDezException extends Exception{
   public MaiorQueDezException (String mensagem){
      super(mensagem);
   }
}
public class A{
     private int valorMenorQueDez;
     // estou dizendo que este método *lança* uma MaiorQueDezException
     // tu precisas coloca-lo entre try { }  ok ?
     public void setValorMenorQueDez(int valorMenorQueDez) throws MaiorQueDezException{
          if (valorMenorQueDez < 10) // aqui valida!
              this.valorMenorQueDez = valorMenorQueDez;
          else
              throw new MaiorQueDezException("NANANINANAO");
           // um pequeno debug... :)
           System.out.println("valorMenorQueDez => " + this.valorMenorQueDez );
     }

     public static void main(Strings [] args){
             A a = new A();
             try{
                   a.setValorMenorQueDez(5);   // esse não lança
                   a.setValorMenorQueDez(50); // esse lança exception
             }catch(MaiorQueDezException mqde){
                   mqde.printStackTrace();  
             }
     }
}

isso vai resultar em

valorMenorQueDez => 5
MaiorQueDezException: NANANINANAO
        at A.setValorMenorQueDez(A.java:12)
        at A.main(A.java:21)

certo ?

O

se deve ser verificada ou nao depende do tipo de erro e de quando vc vai obrigar quem esta usando a sua classe a trata-lo… as Verificadas obrigam o tratamento ou repassar a exceção atraves do ‘throws’ enquanto as não-Verificadas podem ou não ser tratadas, de acordo com a vontade de quem esta implementando

sobre sempre aparecer “sucesso” no seu exemplo: lembre-se sempre que a execução do programa só passa para o bloco ‘catch’ quando a exceção que o bloco try esta protegendo for lançada… e de acordo com o seu exemplo, o System.out.println esta antes do lançamento da exceção, ou seja, sempre imprimirá “sucesso” ! :smiley:

quanto a estar em duvida de usar ‘throw’ ou ‘throws’: uma dica boa para memorizar isso eh lembrar q o throws só é utilizado em assinatura de metodos!! ai fica bem mais facil… por exemplo

public class MeuExemplo{
public void metodo() throws IOException { }
}

significa que quem utilizar o metodo MeuExemplo.metodo(), vai ter q tratar a IOException, ou vai usar outro throws pra repassar quando utilizar:

Tratando a Exceção:

public class TratamentoDeExcecoes{
     public void meuSegundoMetodo(){
            try{
                    MeuExemplo a = new MeuExemplo();
                    a.metodo();
            }catch(IOException e){
                    e.printStackTrace();
            }
      }
}

‘Repassando’ a Exceção

public class TratamentoDeExcecoes{
     public void meuSegundoMetodo() throws IOException{
            MeuExemplo a = new MeuExemplo();
            a.metodo();
}

espero que tenha ajudado a esclarecer as exceções em java :smiley:

Andre_Brito

Hummmmmm… estou começando a entender e já agradeço as respostas, mas ainda assim ficou uma dúvida.
Essa minha exceção verificada é uma classe certo? O que tem dentro dela? Um toString() e o construtor só?? E ela não é tratada? O que isso quer dizer? Que dá pra manipular?

Tipo, to achando estranho porque parece que não me entra a idéia de ter uma classe com 2, 3 métodos que não verificam nada. >(
Tá faltando um artigo sobre isso no GUJ. Procurei e não achei nada.

Obrigado pelas respostas até agora.

Deixa eu formular melhor.

Temos 2 tipos de de exceções: as verificadas e as não verificadas, certo? As não verificadas podem ser tratadas?? O que quer dizer com “tratadas”? Que ele nos retorna a mensagem que passamos por parâmetro pelo construtor?

throw new ArithmeticException("Divisao por 0 nao existe.\n");

E quando não podemos tratar uma exceção? Q q acontece?

Mais uma dúvida (MEU DEUS): exceções não verificadas param a execução? E as verificadas?

sergiotaborda

Todas as exceções podem ser tratadas. Esse é o objetivo de existirem exceções.
A diferença é que para as exceções verificadas o compilador força a regra de tratamento. Ou seja, ele obriga que o programador implemente um tratamento da exceção. O tratamento pode ser feito usando try/catch ou relançando a exceção com throw.

throw -> imperativo do verbo lançar throw = lança!
throws -> que lança

public class metodo () lança A , B {

           lança new A()
}

em portugues é a mesma palavra , mas em inglês não. O primeiro lança (throws) informa que o metodo pode lançar A ou B. O segundo lança(throw) dá a ordem de lançar A

A exceção é verificada se não herdar de RuntimeException e não-verifica se herdar.

As exceções não contém regras. Elas são como eventos. Contém apenas dados que informem os detalhes do problema que aconteceu.

peczenyj

De uma lida nesses 3 textos.



E, sim, uma exception do tipo RuntimeException pode parar a sua aplicação se ela for executada fora de um bloco try{ }

Melhor exemplo é vc tentar fazer uma divisão por 0 ou pegar o indice 50 de um vetor de 10 posições: serão lançadas exception que o compilador não obriga vc a tratar.

Andre_Brito

Bom, 1º de tudo, valeu.

Essa do throw e do throws eu to sabendo. segio, então minhas classesExceptions terão somente um construtor com super dentro dele e não deve fazer verificações, certo? Ou errado?

peczenyj, valeu pelos links cara. Vou ler assim que puder.

E, sim, uma exception do tipo RuntimeException pode parar a sua aplicação se ela for executada fora de um bloco try{ }

Então dentro do try o programa pode continuar a execução né? No caso daí, "cairia" no catch?

Essa do array eu já fiz... usei o IndexOutOfBoundsException e me parece que deu certo.

Deixa eu ver se eu entendi. Se eu usar o bloco try{} catch, minha execução não pára:

public void apresenta(int indice)
    {
        // Com o bloco try - catch, a execucao do programa nao e interrompida.
        try {
            System.out.println("O valor dentro do campo que tem o indice " + indice + " e >>> " + array[indice-1] + ".\n");        }
        catch (IndexOutOfBoundsException e) {
            System.err.println("IndexOutOfBoundsException\n");
        }

Só que, se eu usasse um throw new (como é o nome disso? quando instancia uma nova exceção), a execução iria parar e ia dar um "bip".

[code]
 public void apresenta(int indice)
    {
        if (indice > 50)
                  throw new IndexOutOfBoundsException("IndexOutOfBoundsException\n");
    }

E as duas são tratadas?

sergiotaborda
dedejava:
então minhas classesExceptions terão somente um construtor com super dentro dele e não deve fazer verificações, certo? Ou errado?

Sua execções terão apenas um conjunto de construtores . Se esses constutrutores passam detalhes do erro
devem haver métodos para ler esses detalhes. Por exemplo a exceção MyFileNotFoundException(File) recebe como parametro o arquivo que não foi encontrado. Ele terá que ter um método getFile() para podermos obter essa informação depois.

Então dentro do try o programa pode continuar a execução né? No caso daí, "cairia" no catch?

Se acontece uma exceção de qualquer tipo a execução do codigo seguinte não acontece.
O que acontece é a execução de lançamento da exceção.
O catch é uma forma de interferir com essa execução especial.
Portanto o try não cai no catch. não é como o swith em que um case cai no seguinte

public void apresenta(int indice)
    {
        if (indice > 50)
                  throw new IndexOutOfBoundsException("IndexOutOfBoundsException\n");
    }

E as duas são tratadas?

IndexOutOfBoundsException é uma exeção não verificada.
Verificar é diferente de tratar.
Ali vc está lançando a exeção. Como ela não é verificada o compilador não dá a minima para o que vc está fazendo e deixa passar.
Experimento mudar para throw new Exception("IndexOutOfBoundsException\n");
Vai ver que o compilador não gosta. Ele ai acusar um erro dizendo que a exeção não foi tratada.
Porquê ? Porque ela é verificada. Então o compilador vigia o que vc está fazendo e não deixa passar em branco quando ha uma exceção verificada que não foi tratada.
Para tratar a execção vc tem sempre 2 opções:
1) usar throws na assinatura do método. Isto significa "Não sei tratar esta exceção" e "Métodos que me chamarem vão ter que se haver com esta exceção"
2) usar try/cacth/finally : Aqui vc sabe como tratar e como tal vc cria um codigo que dribla o problema. A exceção será capturada pelo catch e não mais será lançada para o metodo chamador.

Exemplo, o meotodo a seguir transforma strings em double

public double toDouble(String s){
            return Double.parseDouble(s);
}

Double.parseDouble() lança uma exceção não-verificada chamada NumberFormatException que significa que a string não é um numero. Ou é null ou tem espaços a mais , ou contém letras, por exemplo.

Mas no meu método eu quero que quando aconteca esse problema ele retorne 0; Então eu preciso tratar a execção embora ela não seja verificada. E fica assim:

public double toDouble(String s){
try {
           return Double.parseDouble(s);
} catch (NumberFormatException e){
             return 0D;
}
}

Bom ,mas agora eu não quero que dê certo quando s for null . quero que continue enviando
NumberFormatException . Ai fica assim:

public double toDouble(String s){

if (s==null){
 throw new NumberFormatException ();
}

try {
           return Double.parseDouble(s);
} catch (NumberFormatException e){
             return 0D;
}
}

Agora, entenda pq o if é fora do try. E tente entender o que acontece se executar o if dentro do try e s for null.

Não sei se respondi à sua duvida.

Criado 4 de dezembro de 2007
Ultima resposta 5 de dez. de 2007
Respostas 7
Participantes 4