1. 抛出异常
public void proc(){ // Exception是Throwable的继承类,代表最基本的异常 throw new Exception("hello"); }
// 用异常说明,说明该方法要抛出的异常 public void proc() throws Exception{ throw new Exception("hello"); } // 用try块捕获该异常 public void proc(){ try { throw new Exception("hello"); } catch (Exception e) { e.printStackTrace(); } }
异常说明可以是方法抛出的异常类本身,也可以是异常类的基类,比如throws后面可以是throwable。
// RuntimeException或其继承类不需要异常声明 public void proc(){ throw new RuntimeException("hello"); }
public void proc2() throws NullPointerException, FileNotFoundException { }
class A { public void proc() throws Exception { throw new Exception("hello"); } // 异常声明 public void proc1() throws Exception { proc(); } // 异常声明,声明中的类可以是基类 public void proc2() throws Throwable { proc(); } // 直接捕获异常 public void proc3() { try { proc(); } catch (Exception e) { e.printStackTrace(); } } }
class MyException1 extends Exception { } class MyException2 extends Exception { } class A { public void proc() throws MyException1, MyException2{ } }
2. 捕获异常和结束清理
class MyException1 extends Exception { } class MyException2 extends Exception { } class MyException3 extends Exception { } class A { public void proc() throws Exception{ try{ // 仅仅为了演示用 Random random = new Random(); int i = random.nextInt(3); if (i == 0) throw new MyException1(); else if (i == 1) throw new MyException2(); else if (i == 2) throw new MyException3(); } catch(MyException1 e){ // 当抛出MyException1时会跳到这里来。 e.printStackTrace(); } catch(MyException2 e){ // 当抛出MyException2时会跳到这里来。 e.printStackTrace(); } catch (Exception e) { // 当抛出MyException3时,由于上面没有匹配的处理器, // 并且Exception是MyException3的基类,所以会跳到这里来。 e.printStackTrace(); // 可以重新抛出异常,系统将寻找更外层的异常处理器 throw e; } } } public class Main { public static void main(String[] args) { A a = new A(); try { a.proc(); } catch (Exception e) { e.printStackTrace(); } } }
class MyException1 extends Exception { } class A { public void proc(){ try{ throw new MyException1(); } catch(MyException1 e){ e.printStackTrace(); } finally { System.out.println("Hello"); } } } public class Main { public static void main(String[] args) { A a = new A(); a.proc(); } } 最后的输出是: MyException1 at A.proc(Main.java:12) at Main.main(Main.java:27) Hello
3. 异常的限制:对于继承类,它如果所覆盖的方法有异常说明,则所列出的异常类,必须是基类该方法所列出的异常类的子集,先看一个例子:
class MyException1 extends Exception { } class A { public void proc(){ } } class B extends A { // 编译错误:因为A.proc没有异常说明,所以子类也不能有异常说明 // 解决的方法是为A.proc加上异常说明:throws MyException1 // 或者在throw new MyException1();加上try块并去掉异常说明 public void proc() throws MyException1 { throw new MyException1(); } }
再看一下例子:
class MyException1 extends Exception { } class MyException2 extends Exception { } class A { public void proc() throws MyException1 { } } class B extends A { // 错误:因为A.proc只声明了MyException1异常 public void proc() throws MyException2 { } }
构造器是一个例外,继承类可以声明更多的异常类,但必须加上基类所声明的异常类:
class MyException1 extends Exception { } class MyException2 extends Exception { } class A { A() throws MyException1 { } public void proc() throws MyException1 { } } class B extends A { B() throws MyException1, MyException2 { } }