日期:2014-05-20  浏览次数:20741 次

Java异常中的throw问题
众所周知,在JAVA中的一个方法中使用throw关键字抛出异常对象,则要么在该方法中用try..catch语句对这个抛出的异常进行处理,要么将此方法声明为抛出异常,例如public int devide(int x,int y)throws Exception.
但是我在查阅java文档时,发现用src源代码中用throw的地方都没有用上述两种方法进行处理.例如:BigInteger中的其中一个方法:
1 private int parseInt(char[] source, int start, int end) {
2 int result = Character.digit(source[start++], 10);
3 if (result == -1)
4 throw new NumberFormatException(new String(source));
5
6 for (int index = start; index<end; index++) {
7 int nextVal = Character.digit(source[index], 10);
8 if (nextVal == -1)
9 throw new NumberFormatException(new String(source));
10 result = 10*result + nextVal;
11 }
12
13 return result;
14 }
在第7行和9行都抛出了异常对象,但是都没有用try..catch进行处理,也没有将该方法声明为抛出异常类型.

包括JAVA SRC其他的方法皆如此.请问,这个何故,为什么在我们自己写的方法中用throw抛出异常对象时必须进行捕捉或声明.而java自身的代码的就不需要

请高手解答


------解决方案--------------------
throw抛出的异常会由java运行时系统进行捕获处理,这是jdk内部class之间的抛出异常、捕获和处理异常的事情,不涉及外部代码,而我们自己写的方法会包含我们开发者自己定义的代码,我们要捕捉的也是我们自己写的代码中的异常,所以java运行时系统不知道怎么样来处理(总不可能未卜先知开发者写的各式各样的代码吧?)
------解决方案--------------------
这是一个关于异常是否是RuntimeException异常的问题。
Java的异常机制总的来说将异常分为两种类型:运行时异常和非运行是异常,其语法上的判断原则就是看某个异常是否继承于RuntimeException异常类。
运行时异常(也就是继承于RuntimeException类的异常)在Java语法中是unchecked的,也就是允许程序不用try...catch....或者throws去捕获或者声明抛出,因为“运行时”的异常在逻辑上被定义为那种在运行时根据各种复杂的程序环境可能造成的异常,而且往往无法判断在异常发生后应该如何处理,这是,编译器就不强迫用户去写一个try...catch...去捕获或者throws异常了,因为用户既不知道异常是不是会发生,也不一定知道异常发生了该怎么处理。
非运行时异常(也就是那种不是继承于RuntimeException类的异常)是指那种Java语法中checked的异常,也就是用户必须要通过try...catch...去捕获,或者throws声明抛出,这种异常主要针对在软件设计时就会考虑到的各种异常情况,而且用户明确知道怎么处理(比如,数据库连接异常,那么异常发生后就应该给出错误提示,然后关闭链接),这种异常用户在设计的时候会明确知道异常有可能发生,而且明确知道异常发生后应该做什么,然后把异常处理代码写在try...catch...里。
所以楼主给的代码,里面的NumberFormatException,通过查看Javadoc,可以发现它继承于RuntimeException,属于运行时异常,程序本身可以不做try...catch...操作,如果异常发生,则该异常直接上抛给调用栈的下层,直到异常被处理或者抛到程序入口函数为止。
还有一点要提到的是,在设计异常类的时候,区分异常是否是运行时很重要,因为异常类都是人设计的,所以需要人来判断这个异常到底是不是运行时的,如果把运行时的定义成非运行时的,或者反过来,都会惹不少麻烦,我们一般如果不做框架或者是平台,都是直接定义非运行时异常的,运行时异常用得非常少
------解决方案--------------------
回答要分重点的。
Exception:它指出了合理的应用程序想要捕获的条件。Exception又分为两类:一种是CheckedException,一种是UncheckedException。这两种Exception的区别主要是CheckedException需要用try...catch...显示的捕获,而UncheckedException不需要捕获。通常UncheckedException又叫做RuntimeException。《effective java》指出:对于可恢复的条件使用被检查的异常(CheckedException),对于程序错误(言外之意不可恢复,大错已经酿成)使用运行时异常(RuntimeException)。

我们常见的RuntimeExcepiton有IllegalArgumentExceptionIllegalStateExceptionNullPointerExceptionIndexOutOfBoundsException等等。对于那些CheckedException就不胜枚举了,我们在编写程序过程中try...catch...捕捉的异常都是CheckedException。io包中的IOException及其子类,这些都是CheckedException。