黑马程序员——异常机制4:RuntimeException

来源:互联网 发布:网络动作游戏大全 编辑:程序博客网 时间:2024/04/29 23:47

------- android培训、java培训、期待与您交流! ----------

1. RuntimeException特点

我们已经学习了throw关键字,那么我们也可以手动抛出Java类库中已有的异常类对象了,并且同样可以自定义异常信息。比如:

代码1:

class MathTools{//没有进行异常声明public static int division(int x, int y){if(y== 0)//手动抛出Java类库异常,并自定义异常信息throw new ArithmeticException("除数不能为零!"); return x/y;}}class ExceptionDemo{public static void main(String[] args){//没有进行try-catch处理int x = 5, y = 0;int result = MathTools.division(x, y);System.out.println(x+"/"+y+"= "+result);             System.out.println("over");}}
运行结果为:

java.lang.ArithmeticException: 除数不能为零!

提示的异常信息就是自定义的内容了。大家可能会注意到一个问题:虽然在division方法内可能会抛出异常,但是不仅该方法上没有进行异常声明,,甚至主函数中也没有进行trt-catch处理,并且也通过了编译。

通过查阅API文档,可知ArithmeticException类的直接父类是称为RuntimeException类的异常类,该类就是我们前面提到的例外情况:当在方法内可能会抛出RuntimeException(运行时异常)及其子类异常对象时,可以不对其进行任何异常处理,包括try-catch处理和异常声明。

2. RuntimeException的意义

在前面的内容中我们反复使用了除零算数异常,这个异常的特点是,在很大程度上,该问题的产生并非源自程序本身,或者说并不是程序在设计和运行时产生的问题,而是用户使用不当造成的——传入了不符合算数规则的数。

那么在Java语言的规则中,若是由于外界使用不当导致异常产生,那么就不应该对其进行处理(实际上也没有办法进行处理),而是让程序停止,并警告使用者规范其使用方法。

从另一个方面来说,如果将这类异常在方法上进行声明,而外界的使用者对其进行try-catch处理,实际是在隐藏可能会发生的问题,因为处理以后程序可以使用错误的参数照常继续运行,这是没有意义或者危险的。

那么不对该异常进行声明,方法的使用者也就不会进行相应的处理,一旦发生异常,程序就会停止,使用者就会相应修改自己的使用方式,问题也就解决了。

3. RuntimeException举例

1) 例一

需求:账号验证。

分析:定义一个包含账号验证方法的类,调用该方法时传入需要被验证的账号字符串,通过调用传入的账号字符串对象equals方法与目标账号字符串进行比对。当传入null时,由于无法调用equals方法,而发生NullPointerException,该异常也是RuntimeException的子类。

代码:

代码2:

class Checker{public static void countCheck(String count){//调用传入的字符串对象equals方法与目标账号进行比对if(count.equals("Abc"))System.out.println("账号正确");elseSystem.out.println("账号错误");}}class CheckerDemo{public static void main(String[] args){//为演示效果,故意传入nullString count = null;Checker.countCheck(count);}}
运行结果为:

Exception in thread "main"java.lang.NullPointerException

       at Checker.countCheck(CheckerDemo.java:7)

       at CheckerDemo.main(CheckerDemo.java:18)

这里就发生了空指针异常。在定义countCheck方法时,完全可以预见到可能会由于传入null而发生空指针异常,但是这种情况的发生是人为造成,因此不应该进行声明或try-catch处理,因此在运行上述代码时程序停止了。

那么出了问题就需要修改代码。有两种方式修改:

方法一:

if(count != null && count.equals(“Abc”))
只有count类类型变量不指向空时,才调用其equals方法进行判断。

方法二:

if(“Abc”.equals(count))

简便方法是,直接调用目标账号字符串的equals方法进行判断,如果传入null,那么就是打印输出“账号错误”,既避免了异常发生,而对代码改动相对较小。

2) 例二

常见的ArrayIndexOutOfBoundsException——数组角标越界异常也是RuntimeException的子类。同样,如果去访问超过数组长度的数组角标就会发生该异常,而该异常的发生也是由于传入不正确参数导致的。此时也要在测试时使程序停止,提醒程序设计人员修改代码。

4. 自定义异常与RuntimeException的结合

学习了RuntimeException异常的特点以后,当我们在设计自定义异常时,如果该异常的抛出条件也符合RuntimeException的抛出规则就应该使其继承RuntimeException,例如我们前面举的例子——MinusDivisorException,负除数异常。同样我们认为一旦发生了负除数异常就没有必要继续进行下面代码的执行了,因此不需要为该异常进行任何处理动作,而是令程序停止,提醒程序员修改代码。代码体现如下:

代码3:

class MinusDivisorException extendsRuntimeException{MinusDivisorException(Stringmessage){super(message);}}
同样,既不需要为该异常进行声明,也不需要try-catch处理。

至此,我们又可以将Exception细分为两类:

1) 编译时被检测的异常。意思是,当在方法内抛出此类异常,编译时就会检查方法上有没有声明该异常,并且调用该方法的代码有没有进行相应的处理——或继续抛出或try-catch处理。这类异常的特点是:如果真的发生,是可以进行处理的,处理后程序可以继续正常运行。

2) 编译时期不被检测的异常——运行时异常,RuntimeException异常及其子类。当方法中可能会抛出该类异常时,即使未进行任何处理也不会有任何编译失败提示。这类异常的特点是:一旦发生,不能对其进行处理,需要令程序停止,修改代码,否则带着错误参数继续执行代码是危险的。


0 0