【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条
?
?
?
?
?