Jak najłatwiej zdefiniować niestandardową klasę wyjątków w Javie?

286

Próbuję zdefiniować własną klasę wyjątków w najprostszy sposób, a oto, co otrzymuję:

public class MyException extends Exception {}

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

Tak mówi kompilator Java:

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

Miałem wrażenie, że ten konstruktor musi zostać odziedziczony java.lang.Exception, prawda?

yegor256
źródło

Odpowiedzi:

402

Nie, nie „dziedziczysz” domyślnych konstruktorów, musisz zdefiniować ten, który przyjmuje String w swojej klasie. Zwykle używasz super(message)konstruktora do wywoływania konstruktora nadrzędnego. Na przykład:

public class MyException extends Exception {
    public MyException(String message) {
        super(message);
    }
}
djna
źródło
58
@vulkanino: Nie. Domyślny konstruktor jest dodawany przez kompilator dla każdej klasy, która nie definiuje własnego konstruktora. Jeśli zdefiniujesz jawnego konstruktora, nie otrzymasz domyślnej, nawet jeśli nadklasa ją ma, a jeśli twoja klasa nie ma konstruktora, otrzymasz domyślną, nawet jeśli superklasa jej nie ma.
Michael Borgwardt,
5
if your class has no constructor, you get the default even if the superclass does not have itOstatnia część jest niemożliwa, chyba że nadklasa ma domyślnego konstruktora, który jest dostępny dla tej klasy (może być chroniony lub chroniony przez pakiet). W przeciwnym razie musisz jawnie wywołać jednego z konstruktorów nadrzędnych, w przeciwnym razie kompilacja się nie powiedzie.
Sean Patrick Floyd
43
Dodaj konstruktory MyException(Throwable)i, MyException(String, Throwable)aby poprawnie obsługiwać łańcuchy wyjątków .
Danilo Piazzalunga,
8
Prawie 3 lata później i żaden z dodatkowych konstruktorów nie został dodany. :(
byxor
2
@BrandonIbbotson Co rozumiesz przez „one” i gdzie są dodawane? Jeśli to, co rozumiesz przez „oni”, to konstruktory nadklasy, a „gdzie” to podklasa, to się mylisz. Konstruktory nadklasy nie są domyślnie dodawane do podklasy. Ponadto w poprzednich zdaniach nie widzę żadnego innego tematu, na który mogłyby się odnosić te słowa.
halil
90

Typowy niestandardowy wyjątek, który zdefiniuję, jest mniej więcej taki:

public class CustomException extends Exception {

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

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

}

Nawet tworzę szablon za pomocą Eclipse, więc nie muszę pisać wszystkich rzeczy od nowa.

nanda
źródło
17
Możesz po prostu rozszerzyć wyjątek podczas tworzenia swojej klasy w środowisku Eclipse, a otrzymasz wszystkie cztery konstruktory. Nie potrzebujesz szablonu.
jeremyjjbrown
Kiedy powinniśmy użyć drugiego Consutructor zamiast pierwszego?
ZhaoGang,
61

Jeśli użyjesz nowego okna dialogowego klasy w Eclipse, możesz po prostu ustawić pole Superclass na java.lang.Exceptioni zaznaczyć „Constructors from superclass”, a wygeneruje to:

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
    }

}

W odpowiedzi na poniższe pytanie dotyczące nie wywoływania super()defektywnego konstruktora Oracle ma do powiedzenia :

Uwaga: Jeśli konstruktor nie wywołuje jawnie konstruktora nadklasy, kompilator Java automatycznie wstawia wywołanie do konstruktora bez argumentów nadklasy.

Kevin Brey
źródło
22

Powód tego wyjaśniono w artykule o dziedziczeniu platformy Java, który mówi:

„Podklasa dziedziczy wszystkie elementy (pola, metody i klasy zagnieżdżone) z jej nadklasy. Konstruktory nie są członkami , więc nie są dziedziczone przez podklasy, ale konstruktor nadklasy można wywoływać z podklasy”.

Isaq
źródło
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
źródło
co by to zwróciło?
user1876508,
Po prostu wydrukuje „Hello Back Again with niestandardowy wyjątek”, który pochodzi z konstruktora wyjątku UseCusomException, wyjątek zostanie rzucony, a następnie złapany w głównym, który wypisze „To jest mój niestandardowy wyjątek: To jest wyjątek niestandardowy”.
ThePerson
2

Klasa wyjątków ma dwa konstruktory

  • public Exception() - Konstruuje wyjątek bez żadnych dodatkowych informacji. Charakter wyjątku zwykle wywodzi się z nazwy klasy.
  • public Exception(String s) - Tworzy wyjątek z określonym komunikatem o błędzie. Szczegółowy komunikat to ciąg znaków opisujący warunek błędu dla tego konkretnego wyjątku.
Deepak Pakhale
źródło
3
W rzeczywistości od wersji Java 1.4 istnieją jeszcze dwa konstruktory: public Exception(Throwable)i public Exception(String, Throwable). Są one potrzebne do prawidłowego obsługi łańcuchów wyjątków .
Danilo Piazzalunga,
@DaniloPiazzalunga zgadza się z tobą. źródło: Constructor Summary docs.oracle.com/javase/1.5.0/docs/api/java/lang/Exception.html
KNU
0

Jeśli dziedziczysz po wyjątku, musisz podać konstruktor, który przyjmuje parametr jako parametr (będzie zawierał komunikat o błędzie).

vulkanino
źródło
Myślę, że powinieneś również dodać powód.
Jigar Joshi
3
właściwie to jest niepoprawne. Jeśli twój kod używa konstruktora z jednym argumentem String, musisz go zadeklarować. Jednak podklasę wyjątku można zdefiniować bez jawnych konstruktorów ... ponieważ wyjątek ma konstruktor bez argumentów.
Stephen C
0

i nie zapomnij o najprostszym sposobie zgłoszenia wyjątku (nie musisz tworzyć klasy)

if (rgb > MAX) throw new RuntimeException("max color exceeded");
Lorne K.
źródło