ClassCastException(类型转换异常)、IllegalArgumentException(非法参数异常)
public class Test{ public static void main(String[] args) { division(5, 0); } static int division(int a ,int b){ return a/b; } } /* Exception in thread "main" java.lang.ArithmeticException: / by zero at com.tsr.j2seoverstudy.base.Test.division(Test.java:31) at com.tsr.j2seoverstudy.base.Test.main(Test.java:28) */上面的例子就报出了运行时异常:ArithmeticException。因为我们将非法的被除数0作为参数传递给了除法运算的函数内。同时也可以看到,虽然“division”方法可能引发异常,但因为是运行时异常,所以即使不做任何异常处理,程序任然能够通过编译。
但当该类型的异常真的发生的时候,调用者运行的程序就会直接停止运行,并输出相关的异常信息。
通过自定义异常理解检测异常和非检测异常
前面我们说到的都是Java自身已经封装好提供给我们的一些异常类。由此我们可以看到,秉承于“万物皆对象”的思想,Java中的异常实际上也是一种对象。
所以自然的,除了Java本身提供的异常类之外,我们也可以根据自己的需求定义自己的异常类。
这里我想通过比较有趣的简单的自定义异常,结合自己的理解,总结一下Java当中检测异常和非检测异常的使用。
1、编译时检测异常
对于编译时异常,我的理解就是:所有你可以预见、并且能够做出应对的意外状况,都应该通过编译时检测异常的定义的方式进行处理。
举个例子来说:假定我们开了一家小餐馆,除开正常营业的流程之外。自然可能发生一些意外状况,例如:
菜里不小心出现了虫子,出现了头发;或者是餐馆突然停电之类的状况。这些状况是每个经营餐馆的人事先都应该考虑到的情况。
既然我们已经考虑到了这些意外情况发生的可能性,那么自然就应该针对于这些状况做出应对的方案。所以代码可能是这样的:
1、首先,定义两个编译时检测异常类,菜品异常和停电异常:
package com.tsr.j2seoverstudy.exception_demo; /* * 菜品异常 */ public class DishesException extends Exception{ public DishesException() { super("菜品有问题.."); } } package com.tsr.j2seoverstudy.exception_demo; /* * 停电异常 */ public class PowerCutException extends Exception{ PowerCutException(){ super("停电异常.."); } } 2、然后在餐厅类当中,对异常作出处理:package com.tsr.j2seoverstudy.exception_demo; public class MyRestaurant { private static String sicuation; static void doBusiness() throws DishesException, PowerCutException{ if(sicuation.equals("菜里有虫") ||sicuation.equals("菜里有头发")){ throw new DishesException(); } else if(sicuation.equals("停电")){ throw new PowerCutException(); } } public static void main(String[] args) { try { doBusiness(); } catch (DishesException e) { //换一盘菜或退款 } catch (PowerCutException e) { //启动自备发电机 } } } 1、我们已经说过了菜品出现问题和停电之类的意外情况都是我们可以预见的,所以我们首先定义了两个编译时检测异常类用以代表这两种意外情况。2、然后我们在餐厅类当中的营业方法当中做出了声明,如果出现“菜里有虫”或“菜里有头发的问题”,我们就用thorw抛出一个菜品异常;如果“停电”,就抛出停电异常。
3、但是,由于我们抛出这一类异常是因为想告知餐厅的相关人员,在餐厅营业后,可能会出现这些意外情况。所以还应当通过throws告诉他们:营业可能会出现这些意外情况。
4、餐厅相关人员接到了声明。于是制定了方案,当餐厅开始营业后。如果出现了菜品异常,请为客人换一盘菜或退款;如果出现停电异常,请启动店里自备的发电机。
2、运行时异常
对于运行时异常的使用,我个人觉得最常用的情况有两种:
第一、编译时检测异常用于定义那些我们可以提供“友好的解决方案”的情况。那么针对于另外一些状况,可能是我们无法很好的进行解决的。
遇到这种情况,我们可能希望采取一些“强制手段”,那就是直接让你的程序停止运行。这时,就可以使用运行时异常。
第二、如果对异常处理后,又引发一连串的错误的“连锁反应”的时候。
我们先来看一下第一种使用使用情况是怎么样的。例如说:
我们在上面的餐厅的例子中,餐厅即使出现菜品异常或停电异常这一类意外情况。
但针对于这一类的意外情况,我们是能够提供较为妥善的解决方案的。
而通过我们提供的针对于这些异常情况的解决方案进行处理之后,餐厅照常营业,顾客接着用餐(程序依旧能够正常运行)。
但还有一种情况,可能无论我们怎么样友好的尝试进行解决,都难以让顾客满意。这种顾客就是传说中被称为“砸场子”的顾客。