我们如何在 Java 中创建自定义异常?
对于已检查的异常:
public class MyCustomException extends Exception { }
从技术上讲,任何扩展了 Throwable的东西都可以被抛出,但是异常通常是 Exception类的扩展,因此它们是检查过的异常(除了 RuntimeException 或基于它的类,它们不会被检查) ,这与其他常见的可抛出类型 Error不同,后者通常不是设计用来在 JVM 内部以外优雅地处理的。
Throwable
Exception
Error
您也可以将异常设置为非公共的,但是您只能在定义它们的包中使用它们,而不能跨包使用它们。
就抛出/捕获自定义异常而言,它的工作方式与内置的-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的子类(或子类的层次结构)。例如:
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 时)的常用技术。
IOException
FooException
有时会出现这样的情况,即您不希望强制每个方法在其 throw 子句中声明您的异常实现。在这种情况下,您可以创建一个 不受约束异常。未检查的异常是扩展 java.lang.RuntimeException的任何异常(它本身是 java.lang.Exception的子类) :
java.lang.RuntimeException
public class FooRuntimeException extends RuntimeException { ... }
方法可以在不声明 FooRuntimeException异常的情况下引发或传播 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。