读书人

【Core JAVA】错误

发布时间: 2012-09-20 09:36:50 作者: rapoo

【Core JAVA】异常


? 先从?java 异常基础?入手,在学习了这些基本知识后,该思考怎么活学活用,异常使用时的注意点,怎么用好异常这些问题了,可以研究下

Effective Java中异常一章,J2EE项目异常处理。



?-class Throwable

?? ? ? ? ?-RuntimeException

?? ? ? ? ?-IllegalStateException



何时使用异常?

异常应该只用于异常的情况下,而不应该用于正常的控制流。

典型例子是遍历数组,怎么处理数组越界问题?怎么在数组不越界下正常操作?Iterator提供了状态测试方法hasNext()及取值方法next(),next是个状态相关方法,对于Iterator的遍历采取的策略是


for(Iterator<Foo> it = collection.iterator(); it.hasNext(); ){     Foo foo = it.next();     ...}

?对于正常的操作流需要避免使用异常,通常有两种做法:

1.针对“状态相关操作” 提供 “状态测试代码” ?2.“可识别的返回值”

做法1,就要考虑是否存在并发访问时的线程安全问题(竞争条件),“状态相关操作” 和 “状态测试代码”操作的对象是否是跨线程的共享变量,其状态是否可改变,是否需要在访问该变量的时候使用同步。

做法2要考虑是当对象处于不适当状态中返回的可识别值是否是合法的值,如null、-1等。


检测异常与非检测异常的比较与选择

?? ? ?Runtime Exception(运行时异常,非检测异常 unchecked exception) --- 这类异常是程序员没有进行必要的检查,由于疏忽和错误而产生的。通常使用if判断处理。属于虚拟机内部的异常。

?? ? ?非Runtime Exception(编译时异常,检测异常 checked exception) ?-- 常常用try/catch处理。


【理解】:首先异常通常分为两类,Runtime Exception和非Runtime Exception,对于Runtime Exception,中文名为非检测异常,就是程序员没有进行相应的检测而产生的异常,比如,除法中除数为0,某个变量为null,数组越界等等。检测的方法就是在操作前通过if( )进行检测。而检测异常是通过try/catch由编译器来进行检测,而Runtime Exception在编译时是不能检测的,只有运行后才能检测到。

另外在程序中,自定义异常类时public Class xxException extends Exception,该异常是检测异常,

Public Class xxException extends RuntimeException,该异常是非检测异常。

【如何选择】

如果期望调用者能够适当地恢复,对于可恢复情况应该使用检测异常。

对于编程错误或者前提违例(API使用者没有遵守API使用的规范),应该使用非检测异常。

即:如果正确地使用API并不能阻止异常条件的产生,并且一旦产生异常,使用API的程序可以立即采取有用动作,这样使用检测异常时合适的,否则使用非检测异常。

在进行API设计时,我们不要忽略了,异常也是个完全意义上的对象,可以在上面定义任意的方法,这些方法主要用于为捕获异常的代码提供额外的信息,特别是关于引发这个异常条件的信息。对于检测异常提供这样的辅助方法尤为重要,调用者可以获得一些有助于恢复的信息。例如:一个电话用户因为没有在账户中存入足够的钱,而使在一个收费电话上呼叫失败,于是抛出一个检测异常。这个异常应该提供一个访问方法,以便允许客户查询所缺的金额。


5种常见的非检测异常RuntimeException

1. java.lang.NullPointerException

2. java.lang.ArithmeticException ?算数异常(如0作除数,负数被开方)

3. java.lang.ArrayIndexoutofBoundsException

4. java.lang.NumberFormatException 数字格式异常 ? ?

如:“abc” --> int

解决办法是 int的正则判断

String intReg = "^-?[0-9]$";

if(str2.matches(intReg)){

int in2 = Integer.parseInt(str2);

}

5. java.lang.ClassCastException ?类型转换异常

如:Object obj = 3;

String str = (String)obj;

解决方法是

Object obj = 3;

If(obj ?instanceof ?String)

?? String str = (String)obj;


6. java.lang.IllegalArgumentException

抛出的异常表明向方法传递了一个不合法或不正确的参数

7. java.lang.IllegalStateException

因为接收对象的状态而使调用非法,例如:如果在某个对象被正确初始化之前,调用者就企图使用这个对象,就会抛出该异常。

在http://www.cs.duke.edu/csed/ap/subset/doc/ap/java/lang/IllegalStateException.html对该异常有这样的说明

In the AP subset, an IllegalStateException might be thrown if a class invariant isn't satisfied(变量不能让人满意). For example it might be appropriate to throw this exception if a class representing a month in a calendar year is constructed with the integer 15 when only integer values in the range 1-12 represent valid months.


注意:确保抛出异常的条件与该异常的文档中描述的条件一致。

?

后续:

1.《Effective java》第61条

?

?

?

?

?

读书人网 >编程

热点推荐