Как определить пользовательский класс исключений в Java, самый простой способ?

286

Я пытаюсь определить свой собственный класс исключений самым простым способом, и вот что я получаю:

public class MyException extends Exception {}

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

Вот что говорит компилятор Java:

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

У меня было ощущение, что этот конструктор должен быть унаследован java.lang.Exception, не так ли?

yegor256
источник

Ответы:

402

Нет, вы не «наследуете» конструкторы не по умолчанию, вам нужно определить тот, который принимает строку в вашем классе. Обычно вы используете super(message)в своем конструкторе для вызова вашего родительского конструктора. Например, вот так:

public class MyException extends Exception {
    public MyException(String message) {
        super(message);
    }
}
DJNA
источник
58
@vulkanino: Нет. Конструктор по умолчанию добавляется компилятором для каждого класса, который не имеет собственного конструктора. Если вы определите явный конструктор, вы не получите значение по умолчанию, даже если у суперкласса он есть, а если у вашего класса нет конструктора, вы получите значение по умолчанию, даже если у суперкласса его нет.
Майкл Боргвардт
5
if your class has no constructor, you get the default even if the superclass does not have itПоследняя часть невозможна, если только у суперкласса нет конструктора по умолчанию, который доступен для этого класса (может быть защищен или защищен пакетом). В противном случае вы должны явно вызвать один из родительских конструкторов, иначе компиляция не удастся.
Шон Патрик Флойд
43
Пожалуйста , добавьте MyException(Throwable)и MyException(String, Throwable)конструкторы должным образом поддерживать исключение сцепления .
Данило Пьяццалунга
8
Почти 3 года спустя и ни один из дополнительных конструкторов не был добавлен. :(
byxor
2
@BrandonIbbotson Что вы подразумеваете под «они» и где они добавлены? Если то, что вы имели в виду под «они», является конструкторами суперкласса, а «где» - подклассом, то вы ошибаетесь. Конструкторы суперкласса неявно добавляются в подкласс. Кроме того, я не вижу никакой другой темы в предыдущих предложениях для этих слов.
Halil
90

Типичное пользовательское исключение, которое я бы определил, выглядит примерно так:

public class CustomException extends Exception {

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

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

}

Я даже создаю шаблон с использованием Eclipse, поэтому мне не нужно писать все снова и снова.

нанда
источник
17
Вы можете просто расширить Exception при создании вашего класса в Eclipse, и вы получите все четыре конструктора. Вам не нужен шаблон.
jeremyjjbrown
Когда мы должны использовать второго Consutructor вместо первого?
ZhaoGang
61

Если вы используете диалоговое окно нового класса в Eclipse, вы можете просто установить поле Superclass java.lang.Exceptionи отметить «Конструкторы из суперкласса», и оно сгенерирует следующее:

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
    }

}

В ответ на вопрос ниже о том, как не вызывать super()конструктор defualt, Oracle говорит следующее :

Примечание. Если конструктор не вызывает явно конструктор суперкласса, компилятор Java автоматически вставляет вызов в конструктор суперкласса без аргументов.

Кевин Брей
источник
22

Причина этого объясняется в статье о наследовании платформы Java, которая гласит:

«Подкласс наследует все члены (поля, методы и вложенные классы) от своего суперкласса. Конструкторы не являются членами , поэтому они не наследуются подклассами, но конструктор суперкласса может быть вызван из подкласса».

Isaq
источник
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());
        }
    }
}
Дипак Пахале
источник
что это вернет?
user1876508
Он просто распечатает «Hello Back Again с пользовательским исключением», которое происходит из конструктора для UseCusomException, исключение будет сгенерировано, а затем перехвачено в main, которое выведет «Это мое пользовательское исключение: это пользовательское исключение».
ThePerson
2

Исключительный класс имеет два конструктора

  • public Exception() - Это создает исключение без какой-либо дополнительной информации. Характер исключения обычно выводится из имени класса.
  • public Exception(String s) - Создает исключение с указанным сообщением об ошибке. Подробное сообщение - это строка, описывающая условие ошибки для этого конкретного исключения.
Дипак Пахале
источник
3
На самом деле, начиная с Java 1.4, есть еще два конструктора: public Exception(Throwable)и public Exception(String, Throwable). Они необходимы для правильной поддержки цепочки исключений .
Данило Пьяццалунга
@DaniloPiazzalunga согласен с вами. источник: Резюме конструктора docs.oracle.com/javase/1.5.0/docs/api/java/lang/Exception.html
KNU
0

Если вы наследуете от Exception, вы должны предоставить конструктор, который принимает String в качестве параметра (он будет содержать сообщение об ошибке).

vulkanino
источник
Я думаю, что вы должны также добавить причину.
Джигар Джоши
3
на самом деле, это неправильно. Если ваш код использует конструктор с одним аргументом String, вы должны объявить его. Тем не менее, подкласс Exception может быть определен без явных конструкторов ... потому что Exception имеет конструктор без аргументов.
Стивен С
0

и не забудьте самый простой способ вызвать исключение (вам не нужно создавать класс)

if (rgb > MAX) throw new RuntimeException("max color exceeded");
Лорн К
источник