Como definir a classe de exceção personalizada em Java, da maneira mais fácil?

286

Estou tentando definir minha própria classe de exceção da maneira mais fácil, e é isso que estou recebendo:

public class MyException extends Exception {}

public class Foo {
  public bar() throws MyException {
    throw new MyException("try again please");
  }
}

Isto é o que o compilador Java diz:

cannot find symbol: constructor MyException(java.lang.String)

Tive a sensação de que esse construtor deve ser herdado java.lang.Exception, não é?

yegor256
fonte

Respostas:

402

Não, você não "herda" construtores não padrão, precisa definir aquele que recebe uma String em sua classe. Normalmente você usa super(message)em seu construtor para chamar seu construtor pai. Por exemplo, assim:

public class MyException extends Exception {
    public MyException(String message) {
        super(message);
    }
}
djna
fonte
58
@vulkanino: Não. O construtor padrão é adicionado pelo compilador para cada classe que não define construtor próprio. Se você define um construtor explícito, não obtém o padrão, mesmo que a superclasse o possua, e se sua classe não tem construtor, obtém o padrão mesmo que a superclasse não o possua.
Michael Borgwardt
5
if your class has no constructor, you get the default even if the superclass does not have itA última parte é impossível, a menos que a superclasse tenha um construtor padrão acessível a essa classe (pode ser protegido ou protegido por pacote). Caso contrário, você deve chamar explicitamente um dos construtores pai, ou a compilação falhará.
Sean Patrick Floyd
43
Por favor, adicione os construtores MyException(Throwable)e MyException(String, Throwable)para suportar adequadamente o encadeamento de exceções .
Danilo Piazzalunga
8
Quase 3 anos depois e nenhum dos construtores extras foi adicionado. :(
byxor
2
@BrandonIbbotson O que você quer dizer com 'eles' e onde eles são adicionados? Se o que você quis dizer com 'eles' são construtores de superclasse e 'onde' é subclasse, você está errado. Os construtores de superclasse não são implicitamente adicionados à subclasse. Além disso, não consigo ver nenhum outro assunto nas frases anteriores para que essas palavras se refiram.
Halil
90

Uma exceção personalizada típica que eu definiria é algo como isto:

public class CustomException extends Exception {

    public CustomException(String message) {
        super(message);
    }

    public CustomException(String message, Throwable throwable) {
        super(message, throwable);
    }

}

Eu até crio um modelo usando o Eclipse, para não precisar escrever todas as coisas repetidamente.

Nanda
fonte
17
Você pode apenas estender a exceção ao criar sua classe no Eclipse e obterá todos os quatro construtores. Você não precisa de um modelo.
precisa saber é o seguinte
Quando devemos usar o segundo Consutructor em vez do primeiro?
ZhaoGang
61

Se você usar o novo diálogo de classe no Eclipse, poderá definir o campo Superclasse como java.lang.Exceptione marcar "Construtores da superclasse" e isso gerará o seguinte:

package com.example.exception;

public class MyException extends Exception {

    public MyException() {
        // TODO Auto-generated constructor stub
    }

    public MyException(String message) {
        super(message);
        // TODO Auto-generated constructor stub
    }

    public MyException(Throwable cause) {
        super(cause);
        // TODO Auto-generated constructor stub
    }

    public MyException(String message, Throwable cause) {
        super(message, cause);
        // TODO Auto-generated constructor stub
    }

}

Em resposta à pergunta abaixo sobre não chamar super()o construtor defualt, a Oracle tem o seguinte a dizer :

Nota: Se um construtor não chamar explicitamente um construtor de superclasse, o compilador Java inserirá automaticamente uma chamada para o construtor sem argumento da superclasse.

Kevin Brey
fonte
22

A razão para isso é explicada no artigo Herança da plataforma Java, que diz:

"Uma subclasse herda todos os membros (campos, métodos e classes aninhadas) de sua superclasse. Os construtores não são membros e , portanto, não são herdados pelas subclasses, mas o construtor da superclasse pode ser chamado a partir da subclasse."

Isaq
fonte
19
package customExceptions;

public class MyException extends Exception{

    public MyException(String exc)
    {
        super(exc);
    }
    public String getMessage()
    {
        return super.getMessage();
    }
}

import customExceptions.MyException;

public class UseCustomException {

    MyException newExc=new MyException("This is a custom exception");

    public UseCustomException() throws MyException
    {
        System.out.println("Hello Back Again with custom exception");
        throw newExc;       
}

    public static void main(String args[])
    {
        try
        {
            UseCustomException use=new UseCustomException();
        }
        catch(MyException myEx)
        {
            System.out.println("This is my custom exception:" + myEx.getMessage());
        }
    }
}
Deepak Pakhale
fonte
o que isso retornaria?
user1876508
Ele simplesmente imprimiria "Olá, novamente com exceção personalizada", que é do construtor de UseCusomException, a exceção seria lançada e capturada no principal que imprimiria "Esta é minha exceção personalizada: Esta é uma exceção personalizada".
ThePerson
2

A classe de exceção possui dois construtores

  • public Exception() - Isso cria uma exceção sem nenhuma informação adicional. A natureza da exceção geralmente é inferida a partir do nome da classe.
  • public Exception(String s) - Constrói uma exceção com a mensagem de erro especificada. Uma mensagem de detalhe é uma String que descreve a condição de erro para essa exceção específica.
Deepak Pakhale
fonte
3
Na verdade, desde o Java 1.4, existem mais dois construtores: public Exception(Throwable)e public Exception(String, Throwable). Eles são necessários para suportar adequadamente o encadeamento de exceções .
Danilo Piazzalunga
@DaniloPiazzalunga concorda com você. source: Resumo do Construtor docs.oracle.com/javase/1.5.0/docs/api/java/lang/Exception.html
KNU
0

Se você herdar de Exception, precisará fornecer um construtor que use uma String como parâmetro (ela conterá a mensagem de erro).

vulkanino
fonte
Eu acho que você deve adicionar razão também.
Jigar Joshi 23/09/10
3
na verdade, isso está incorreto. Se o seu código usa um construtor com um argumento String, você deve declará-lo. No entanto, uma subclasse Exception pode ser definida sem construtores explícitos ... porque Exception possui um construtor no-args.
Stephen C
0

e não esqueça a maneira mais fácil de lançar uma exceção (você não precisa criar uma classe)

if (rgb > MAX) throw new RuntimeException("max color exceeded");
Lorne K
fonte