Як визначити спеціальний клас виключень у 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, чи не так?

Відповіді:


402

Ні, ви не «успадковуєте» конструктори, що не використовуються за замовчуванням, вам потрібно визначити той, хто приймає String у вашому класі. Зазвичай ви використовуєте super(message)у своєму конструкторі для виклику батьківського конструктора. Наприклад, наприклад:

public class MyException extends Exception {
    public MyException(String message) {
        super(message);
    }
}

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 Що ви маєте на увазі під «вони», і де вони додаються? Якщо те, що ви мали на увазі під «вони», - це конструктори надкласового рівня, а «де» - підклас, то ви помиляєтесь. Конструктори надкласових категорій не додаються неявно до підкласу. Плюс я не бачу жодної іншої теми в попередніх реченнях для цих слів.
халіл

90

Типовий спеціальний виняток, який я б визначив, є приблизно таким:

public class CustomException extends Exception {

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

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

}

Я навіть створюю шаблон за допомогою Eclipse, тому мені не доведеться писати всі речі знову і знову.


17
Ви можете просто розширити виняток під час створення класу в Eclipse, і ви отримаєте всі чотири конструктори. Вам не потрібен шаблон.
jeremyjjbrown

Коли нам слід використовувати другий консульт, а не перший?
ЧжаоГанг

61

Якщо ви використовуєте діалог нового класу в Eclipse, ви можете просто встановити поле Суперклас 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 автоматично вставляє виклик в конструктор без аргументів надкласу.


1
Чому конструктору за замовчуванням не потрібно дзвонити super()?
припинення


22

Причина цього пояснюється в статті про спадкування платформи Java, яка говорить:

"Підклас успадковує всі члени (поля, методи та вкладені класи) від його надкласу. Конструктори не є членами , тому вони не успадковуються підкласами, але конструктор надкласу може бути викликаний з підкласу."


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());
        }
    }
}

що це поверне?
користувач1876508

Це було б просто роздрукувати "Здравствуйте. Знову з користувальницьким винятком", який є з конструктора UseCusomException, виняток буде кинуто, а потім потрапить у головне, яке роздрукує "Це моє спеціальне виключення: Це спеціальне виключення".
ThePerson

2

Клас винятку має два конструктори

  • public Exception() - Це створює виняток без додаткової інформації. Природа винятків зазвичай випливає з імені класу.
  • public Exception(String s) - Побудовує виняток із вказаним повідомленням про помилку. Детальне повідомлення - це рядок, який описує умову помилки для цього конкретного винятку.

3
Насправді, оскільки у Java 1.4 є ще два конструктори: public Exception(Throwable)і public Exception(String, Throwable). Вони необхідні для належної підтримки ланцюжків винятків .
Данило П'яццалунга

@DaniloPiazzalunga згоден з вами. Джерело: Constructor Summary docs.oracle.com/javase/1.5.0/docs/api/java/lang/Exception.html
KNU

0

Якщо ви успадковуєте програму Exception, ви повинні надати конструктор, який бере параметр String (він буде містити повідомлення про помилку).


Я думаю, вам слід також додати розум.
Джигар Джоші

3
насправді це неправильно. Якщо у вашому коді використовується конструктор з одним аргументом String, вам доведеться оголосити його. Однак підклас Exception може бути визначений без явних конструкторів ... тому що у "Exception" є конструктор без аргументів.
Стівен С

0

і не забувайте найпростіший спосіб кинути виняток (вам не потрібно створювати клас)

if (rgb > MAX) throw new RuntimeException("max color exceeded");
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.