Skip to content

Latest commit

 

History

History
100 lines (82 loc) · 3.04 KB

03_Exception_Handling.md

File metadata and controls

100 lines (82 loc) · 3.04 KB

《《《 返回首页
《《《 上一节

异常处理

try 语句中,每个 catch 子句检查抛出的异常是否与给定的类型匹配。 这与实例测试执行的检查相同,因此也适用相同的限制:该类型必须是可验证的。 此 外,catch 子句中的类型必须是 Throwable 的子类。 由于创建不能出现在 catch 子句中的 Throwable 的子类没什么意义,因此如果您尝试创建 Throwable 的参数化子类,Java 编译器会发出警告。

例如,下面是一个新的异常的允许定义,它包含一个整数值:

class IntegerException extends Exception {
  private final int value;
  public IntegerException(int value) { 
    this.value = value; 
  }
  public int getValue() { 
    return value; 
  }
}

这里是一个简单的例子,说明如何使用异常:

class IntegerExceptionTest {
  public static void main(String[] args) {
    try {
      throw new IntegerException(42);
    } catch (IntegerException e) {
      assert e.getValue() == 42;
    }
  }
}

try 语句的主体用 catch 语句捕获的给定值抛出异常。

相反,以下定义的新异常是禁止的,因为它创建了一个参数化类型:

class ParametricException<T> extends Exception { // 编译报错
  private final T value;
  public ParametricException(T value) {
    this.value = value; 
  }
  public T getValue() { 
    return value; 
  }
}

试图编译上述报告错误:

% javac ParametricException.java
ParametricException.java:1: a generic class may not extend
java.lang.Throwable
class ParametricException<T> extends Exception { // 编译报错
                                  ^
1 error

这种限制是明智的,因为几乎任何捕捉这种异常的尝试都必须失败,因为该类型不可确定。 人们可能会期望典型的例外使用如下所示:

class ParametricExceptionTest {
  public static void main(String[] args) {
    try {
      throw new ParametricException<Integer>(42);
    } catch (ParametricException<Integer> e) { // compile-time error
      assert e.getValue()==42;
    }
  }
}

这是不允许的,因为 catch 子句中的类型是不可确定的。 在撰写本文时,Sun 编译器在这种情况下报告了一系列语法错误:

% javac ParametricExceptionTest.java
ParametricExceptionTest.java:5: <identifier> expected
} catch (ParametricException<Integer> e) {
                           ^
ParametricExceptionTest.java:8: ')' expected
}
^
ParametricExceptionTest.java:9: '}' expected
}
^
3 errors

由于异常不能是参数化的,因此语法受到限制,因此必须将该类型编写为标识符,而没有以下参数。

Throwable 子句中输入变量虽然 Throwable 的子类不能是参数化的,但可以在方法声明的 throws 子句中使用类型变量。此技术在第 9.3 节中说明。

《《《 下一节
《《《 返回首页