1.为什么要用异常机制
所以当然要捕获这个异常 给用户一个良好的出错提示。
2.出现异常不处理,程序会终止,程序终止了,系统不能正常运行。
3.因为程序的执行过程中总会遇到许多可预知或不可预知的错误事件,例如说,由于内存资源有限导致需要分配的内存失败了;
或某个目录下本应存在的一个文件找不着了;或说不小心被零除了、内存越界了、数组越界了等等。这些错误事件存在非常大的隐患,
因此程序员总需要在程序中不断加入if语句,来判断是否有异常出现,如果有,就必须要及时处理,否则可能带来意想不到的,甚至是灾难性的后果。
这样一来,程序可读性差了很多,总是有许多与真正工作无关的代码,而且也给程序员增加了极大的工作负担,
多数类似的处理错误的代码模块就像满山的牛屎一样遍地都是(程序员不大多是“牛”人吗?所以。。。哈哈)。 使用异常处理后:
1、把错误处理和真正的工作分开来; 2、 代码更易组织,更清晰,复杂的工作任务更容易实现; 3、 毫无疑问,更安全了,不至于由于一些小的疏忽而使程序意外崩溃了; 4、 由于C++中的try catch可以分层嵌套,所以它提供了一种方法使得程序的控制流可以安全的跳转到上层(或者上上层)的错误处理模块中去。(不同于return语句,异常处理的控制流是可以安全地跨越一个或多个函数)。
2. try、catch、finally语句块的执行顺序:
1)当try没有捕获到异常时:try语句块中的语句逐一被执行,程序将跳过catch语句块,执行finally语句块和其后的语句;
2)当try捕获到异常,catch语句块里没有处理此异常的情况:当try语句块里的某条语句出现异常时,而没有处理此异常的catch语句块时,此异常将会抛给JVM处理,finally语句块里的语句还是会被执行,但finally语句块后的语句不会被执行;
3)当try捕获到异常,catch语句块里有处理此异常的情况:在try语句块中是按照顺序来执行的,当执行到某一条语句出现异常时,程序将跳到catch语句块,并与catch语句块逐一匹配,找到与之对应的处理程序,其他的catch语句块将不会被执行,而try语句块中,出现异常之后的语句也不会被执行,catch语句块执行完后,执行finally语句块里的语句,最后执行finally语句块后的语句;
图2 图示try、catch、finally语句块的执行
使用throw抛出异常
throw总是出现在函数体中,用来抛出一个Throwable类型的异常。程序会在throw语句后立即终止,它后面的语句执行不到,然后在包含它的所有try块中(可能在上层调用函数中)从里向外寻找含有与其匹配的catch子句的try块。
我们知道,异常是异常类的实例对象,我们可以创建异常类的实例对象通过throw语句抛出。该语句的语法格式为:
throw new exceptionname;
例如抛出一个IOException类的异常对象:
throw new IOException;
要注意的是,throw 抛出的只能够是可抛出类Throwable 或者其子类的实例对象。下面的操作是错误的:
throw new String("exception");
这是因为String 不是Throwable 类的子类。
如果抛出了检查异常,则还应该在方法头部声明方法可能抛出的异常类型。该方法的调用者也必须检查处理抛出的异常。
如果所有方法都层层上抛获取的异常,最终JVM会进行处理,处理也很简单,就是打印异常消息和堆栈信息。如果抛出的是Error或RuntimeException,则该方法的调用者可选择处理该异常。
- package Test;
- import java.lang.Exception;
- public class TestException {
- static int quotient(int x, int y) throws MyException { // 定义方法抛出异常
- if (y < 0) { // 判断参数是否小于0
- throw new MyException("除数不能是负数"); // 异常信息
- }
- return x/y; // 返回值
- }
- public static void main(String args[]) { // 主方法
- int a =3;
- int b =0;
- try { // try语句包含可能发生异常的语句
- int result = quotient(a, b); // 调用方法quotient()
- } catch (MyException e) { // 处理自定义异常
- System.out.println(e.getMessage()); // 输出异常信息
- } catch (ArithmeticException e) { // 处理ArithmeticException异常
- System.out.println("除数不能为0"); // 输出提示信息
- } catch (Exception e) { // 处理其他异常
- System.out.println("程序发生了其他的异常"); // 输出提示信息
- }
- }
- }
- class MyException extends Exception { // 创建自定义异常类
- String message; // 定义String类型变量
- public MyException(String ErrorMessagr) { // 父类方法
- message = ErrorMessagr;
- }
- public String getMessage() { // 覆盖getMessage()方法
- return message;
- }
- }
-
6.自定义异常
使用Java内置的异常类可以描述在编程时出现的大部分异常情况。除此之外,用户还可以自定义异常。用户自定义异常类,只需继承Exception类即可。
在程序中使用自定义异常类,大体可分为以下几个步骤。
(1)创建自定义异常类。
(2)在方法中通过throw关键字抛出异常对象。
(3)如果在当前抛出异常的方法中处理异常,可以使用try-catch语句捕获并处理;否则在方法的声明处通过throws关键字指明要抛出给方法调用者的异常,继续进行下一步操作。
(4)在出现异常方法的调用者中捕获并处理异常。在上面的“使用throw抛出异常”例子已经提到了。
-
如果java类库中有的异常可以直接捕获,如果是自己定义的异常类,需要在方法中抛出异常,然后才可以用catch去捕获
- 捕获自定义异常,只有在自定义异常被抛出处,才能去捕捉,如果没有抛出,无法进行捕捉动作
-