如何用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,不是吗?

Answers:


402

不,您没有“继承”非默认构造函数,需要在类中定义一个采用String的构造函数。通常,您super(message)在构造函数中使用来调用父构造函数。例如,像这样:

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

58
@vulkanino:否。编译器会为没有定义自己的构造函数的每个类添加默认构造函数。如果定义显式构造函数,则即使超类具有默认构造函数,也不会获得默认值;如果您的类没有构造函数,则即使超类没有默认构造函数,也将获得默认值。
Michael Borgwardt's

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)构造函数以正确支持异常链接
2013年

8
近三年后,没有添加任何额外的构造函数。:(
byxor 2016年

2
@BrandonIbbotson您的“他们”是什么意思,它们加在哪里?如果“它们”的意思是超类构造函数,而“ where”的意思是子类,那么您错了。超类构造函数不会隐式添加到子类中。另外,在以前的句子中,我看不到任何其他主题可供参考。
halil

90

我定义的一个典型的自定义异常是这样的:

public class CustomException extends Exception {

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

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

}

我什至使用Eclipse创建了一个模板,因此不必一遍又一遍地编写所有内容。


17
您可以在Eclipse中创建Class时扩展Exception,然后将获得所有四个构造函数。您不需要模板。
jeremyjjbrown 2014年

什么时候应该使用第二个Consutructor而不是第一个?
赵刚

61

如果您在Eclipse中使用新的类对话框,则只需将Superclass字段设置为java.lang.Exception并选中“ Constructors from superclass”,它将生成以下内容:

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()
ceving


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

这会返回什么?
2013年

它只会打印出UseCusomException的构造函数中的“ Hello Back Again with custom exception”,该异常将被抛出,然后被捕获到主程序中,该主体将打印出“这是我的自定义异常:这是一个自定义异常”。
ThePerson

2

异常类具有两个构造函数

  • public Exception() -这会构造一个没有任何其他信息的Exception.Exception的性质通常是从类名推断出来的。
  • public Exception(String s) -构造具有指定错误消息的异常。详细消息是描述此特定异常的错误条件的字符串。

3
实际上,从Java 1.4开始,有两个构造函数:public Exception(Throwable)public Exception(String, Throwable)。需要它们来适当地支持异常链接
Danilo Piazzalunga

@DaniloPiazzalunga同意您的观点。来源:构造函数摘要 docs.oracle.com/javase/1.5.0/docs/api/java/lang/Exception.html
KNU

0

如果从Exception继承,则必须提供一个将String作为参数的构造函数(它将包含错误消息)。


我认为您也应该添加理由。
Jigar Joshi

3
实际上,这是不正确的。如果您的代码使用带有一个String参数的构造函数,则必须对其进行声明。但是,可以在没有显式构造函数的情况下定义Exception子类...因为Exception具有无参数的构造函数。
斯蒂芬·C 2010年

0

并且不要忘记引发异常的最简单方法(您无需创建类)

if (rgb > MAX) throw new RuntimeException("max color exceeded");
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.