调用方法时的异常处理

Exception handling when calling a method

假设我有一个方法 'position',它需要 2 个坐标并创建一个位置对象来保存它们。为了确保这些坐标没有超出范围,将抛出 InvalidPositionException .

public Position(int x, int y) throws InvalidPositionException {
    try {
        if (x > 10 || x < 1 || y>10 || y<1) {   
            throw new InvalidPositionException("Position x = "+x+", y = "+y+" is out of bounds");
        } else {
            setX(x);
            setY(y);
        }
    } catch (InvalidPositionException e) {
        System.err.println(e);
    }
}

如果我现在想从另一个 class 创建一个新的位置对象,我会收到错误消息 "unreported exception InvalidPositionException; must be caught or declared to be thrown"

如何在创建新位置对象的方法的方法签名中不声明 "throws" 的情况下完成这项工作?

转到 class InvalidPositionException 并使其继承自 RuntimeException

RuntimeException是unchecked exceptions,意思是编译器不会强制你去处理它们。当您超出数组范围时,这就是一个很好的例子。您不必在每次访问数组时都编写代码来处理这个问题(比如我们如何处理 IOException)。一个类似的例子是NullPointerException。但是,在这两种情况下,您都可以编写代码来捕获异常并进行处理。

如果您是检查异常的纯粹主义者并且不想要 try-catch 块,则另一种处理该问题的方法是在您输入数据的任何屏幕中清理数据并说它不在边界那里。

您需要在创建 Position 对象的语句周围包含一个 try-catch 块。

Position myPosition = null;
try {
  myPosition = new Position(a, b);
}
catch (InvalidPositionException e) {
  // do something if the exception is caught
}

来自约书亚·布洛赫 Effective Java

Item 72: Favor the use of standard exceptions

An attribute that distinguishes expert programmers from less experienced ones is that experts strive for and usually achieve a high degree of code reuse. Exceptions are no exception to the rule that code reuse is a good thing. The Java libraries provide a set of exceptions that covers most of the exception-throwing needs of most APIs. ...

IllegalArgumentException occasions for use - Non-null parameter value is inappropriate

此代码是 IllegalArgumentException 的典型示例。它扩展了 RuntimeException,因此您不需要捕获它。

public Position(int x, int y) {
    if (x > 10 || x < 1 || y>10 || y<1) {   
        throw new IllegalArgumentException("Position x = "+x+", y = "+y+" is out of bounds");
    } 
    setX(x);
    setY(y);
}

P.S。您可能只需将 setX(x) 替换为 this.x = x 并将 y 替换为相同的(如果这些设置器中没有额外的逻辑)。