Java异常处理机制详述(2)

throw关键字用于在某个语句处抛出一个异常,只要执行到这个语句就表示必定抛出异常。
throws关键字用于在方法处抛出一个或多个异常,这表示执行这个方法可能会抛出异常。

throw OBJECT; throw new EXCEPTION("Message"); method() throws EXCEPTION1[,EXCEPTION2...] {}

对于Exception类(非RuntimeException)的异常即已检查异常类,在调用时要么进行捕捉,要么继续向上级抛出。这类错误产生和处理的过程为:

方法f()内部的方法体的throw向上抛出给方法f();

方法f()的throws向上抛出抛给f()调用者;

方法调用者必须捕捉处理,或者不想捕捉就继续向上抛出;

每一级的调用者都不想捕捉而是一直向上抛出,则最后由java虚拟机报错:"未报告的异常错误XXXX必须对其进行捕获或声明以便抛出"。

以下是抛出异常的一个简单示例,抛出的是ArithmeticException异常,因为是RuntimeException类异常,因此从方法体内部throw抛出后,无需在方法定义处使用throws继续抛出。

public class EX { void f(int n) { // 或void f(int n) throws ArithmeticException {} if (n == 0) { throw new ArithmeticException("hello Exception!"); } else { System.out.println("right!"); } } public static void main(String[] args) { EX m = new EX(); m.f(1); m.f(0); // throw Exception } }

执行结果:

right! Exception in thread "main" java.lang.ArithmeticException: hello Exception! //异常的信息 at EX.f(EX.java:4) //真实产生异常的地方 at EX.main(EX.java:13) //调用产生异常的地方

所以,对于RuntimeException类异常来说,是否使用throws关键字并无影响。一般来说,Exception类异常但非RuntimeException才需要使用throws关键字,因为Exception类异常必须要被捕获并处理,而RuntimeException异常则无所谓。

例如将上面的ArimeticException改为FileNotFoundException,前者为Runtime类异常,而后者为Exception但非Runtime类异常,因此使用throw抛出后,必须在定义方法处也使用throws抛出错误。这一过程是"向上级抛出"的过程:"方法体内部抛出异常-->抛给方法本身"

void f(int n) throws FileNotFoundException { if (n == 0) { throw new FileNotFoundException("hello Exception!"); //throw a new yichang duixiang } else { System.out.println("right!"); } }

如果不使用throws关键字抛出错误,则将报错:

EX.java:6: 错误: 未报告的异常错误FileNotFoundException; 必须对其进行捕获或声明以便抛出 throw new FileNotFoundException("hello Exception!"); //throw a new yichang duixiang

从方法f()抛出向上抛出给调用者后,调用者要么使用try-catch捕捉,要么继续向上抛出,否则报错。例如捕捉

import java.io.*; public class EX { void f(int n) throws FileNotFoundException { if (n == 0) { throw new FileNotFoundException("hello Exception!"); } else { System.out.println("right!"); } } public static void main(String[] args) { try { EX m = new EX(); m.f(0); } catch (FileNotFoundException e) { System.out.println(e); } System.out.println("out of try-catch"); } }

如果不捕捉,则可以继续在方法处向上抛出:

public static void main(String[] args) throws FileNotFoundException { EX m = new EX(); m.f(0); } 抛出异常时的注意事项

throw可以同时定义可能抛出的多种异常,尽管这些异常存在继承关系。这时在捕捉异常时,应该先捕捉子类,再捕捉父类。

例如FileNotFoundException是IOException的子类,可以同时:

throws FileNotFoundException,IOException

捕捉时应先捕捉FileNotFoundException,再IOException。

try { ... } catch (FileNotFoundException e) { ... } catch (IOException e) { ... }

在重写有throws子句的方法时,需要注意:

子类重写父类方法要抛出与父类一致的异常,或者不抛出异常

子类重写父类方法所抛出的Exception类异常不能超过父类的范畴

子类重写父类方法抛出的异常可以超出父类范畴,但超出的部分必须是RuntimeException类的异常

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/b04196276bc4d120a2ede155f317459f.html