如何在 Java 中创建自定义异常?

我们如何在 Java 中创建自定义异常?

272169 次浏览

对于已检查的异常:

public class MyCustomException extends Exception { }

从技术上讲,任何扩展了 Throwable的东西都可以被抛出,但是异常通常是 Exception类的扩展,因此它们是检查过的异常(除了 RuntimeException 或基于它的类,它们不会被检查) ,这与其他常见的可抛出类型 Error不同,后者通常不是设计用来在 JVM 内部以外优雅地处理的。

您也可以将异常设置为非公共的,但是您只能在定义它们的包中使用它们,而不能跨包使用它们。

就抛出/捕获自定义异常而言,它的工作方式与内置的-throw via 异常类似

throw new MyCustomException()

抓住 Via

catch (MyCustomException e) { }
public class MyException extends Exception {
// special exception code goes here
}

抛出它作为:

 throw new MyException ("Something happened")

捕捉:

catch (MyException e)
{
// something
}

为了定义 检查过了异常,需要创建 java.lang.Exception的子类(或子类的层次结构)。例如:

public class FooException extends Exception {
public FooException() { super(); }
public FooException(String message) { super(message); }
public FooException(String message, Throwable cause) { super(message, cause); }
public FooException(Throwable cause) { super(cause); }
}

可能抛出或传播此异常的方法必须声明它:

public void calculate(int i) throws FooException, IOException;

... 并且调用此方法的代码必须处理或传播此异常(或两者兼而有之) :

try {
int i = 5;
myObject.calculate(5);
} catch(FooException ex) {
// Print error and terminate application.
ex.printStackTrace();
System.exit(1);
} catch(IOException ex) {
// Rethrow as FooException.
throw new FooException(ex);
}

在上面的示例中,您将注意到 IOException被捕获并作为 FooException重新抛出。这是用于封装异常(通常在实现 API 时)的常用技术。

有时会出现这样的情况,即您不希望强制每个方法在其 throw 子句中声明您的异常实现。在这种情况下,您可以创建一个 不受约束异常。未检查的异常是扩展 java.lang.RuntimeException的任何异常(它本身是 java.lang.Exception的子类) :

public class FooRuntimeException extends RuntimeException {
...
}

方法可以在不声明 FooRuntimeException异常的情况下引发或传播 FooRuntimeException异常; 例如。

public void calculate(int i) {
if (i < 0) {
throw new FooRuntimeException("i < 0: " + i);
}
}

未检查异常通常用于表示程序员错误,例如将无效参数传递给方法或试图突破数组索引界限。

java.lang.Exception0类是可以在 Java 中抛出的所有错误和异常的根。java.lang.Exception1和 java.lang.Exception2都是 java.lang.Exception3的亚类。任何子类 java.lang.Exception3都可能被抛出或捕获。然而,捕获或抛出 java.lang.Exception5通常是不好的做法,因为它用于表示 JVM 内部的错误,这些错误通常不能由程序员“处理”(例如 java.lang.Exception6)。同样,您应该避免捕获 java.lang.Exception3,这可能导致您捕获除 java.lang.Exception9之外的 java.lang.Exception5。