A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 逆风TO 黑马粉丝团   /  2019-7-19 17:04  /  593 人查看  /  0 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 逆风TO 于 2019-7-19 17:13 编辑

前言
何为异常?
举个例子:如我们的程序需要对数据库做一个插入的操作,但是可以会因为各种原因而导致发生了错误,这些错误中包含我们能预见的错误,同时也包含了我们不能预见的错误,而为了解决这些在运行中可能出现的错误,每个编程语言都有其对错误的处理。
而Java中专门引入了异常(Exception:翻译过来为例外),异常机制可以及时有效的帮助开发者处理程序中运行的错误。
Java异常种类可分为:
  •   编译时异常:Java.lang.Exception
  •   运行期异常:Java.lang.RuntimeException
  •   错误:Java.lang.Error

所有异常对象的根基类是Throwable,也就是说Java中所有的Exception和Error都是Throwable类的子孙类,而Throwable直接继承Object类。
1.png
编译时异常:
从程序语法角度讲是必须进行处理的异常,Java编译器强制要求处理这类异常,如果不捕获这类异常,程序将不能被编译。如下例代码:
2.png
上面代码在进行一个读取文件的操作,如果不捕获异常,程序将不能通过编译。
运行期异常:
程序中可以捕获,也可以不捕获,这样的异常一般是由程序逻辑错误引起的,需要修改程序来避免,如数组越界、空指针异常等。该类异常的特点是编译器不会去检查它,也就是说即使你在代码里面没有去捕获该类异常,也将编译通过。
3.png
该段代码编译期间并不需要显示的去捕获任何异常,但是在程序运行期间,当代码执行到if(i == 0)时将产生空指针异常。
错误:
是程序无法处理的错误,一般很少会发生,通常与代码无关,而是和Java虚拟机有关,一旦发生了即表示程序发生了比较严重问题。比较典型的Error就是OutOfMemoryError,表示JVM 内存溢出了。
异常处理机制
在 Java 应用程序中,Java异常处理通过5个关键字try、catch、throw、throws、finally进行管理,异常处理机制分为:
  • 捕获异常
  • 抛出异常

捕获异常:使用try、catch、finally关键字来捕获异常,使程序发生异常时不中断,从而能够继续往下执行。通过上面的代码做一下改进,如:

1  public static void main(String[] args) {  2       Integer i = null;   
3         try{   
4          if(i == 0){         
5                 System.out.println(0);         
6                  }  
7       }catch(RuntimeException e){     
8          System.out.println("发生异常");   
9         }  
10     System.out.println(1);
11 }
运行上面代码执行到if(i == 0)时将产生空指针异常,这时程序将跳到catch代码中执行,会先打印发生异常,由于发生异常的代码我们使用try进行捕获了,再执行完catch代码块后程序将继续往下执行打印1。
通常,我们在日常编程中进行异常捕获时应该根据程序的需要来决定是否增加finally块,在Java程序中如果增加了finally代码块时无论是否发生异常,finally代码块都将执行。如进行一个IO操作时,无论程序是否发生异常都需要关闭流,这时就应该关闭流的操作放入finally中,如:
5.png
通俗一点讲就是catch代码块不一定执行,但是finally块一定会执行。PS:在catch块中可以调用printStackTrace方法打印出堆栈的异常信息,但是这种方式只建议在开发环境下进行。
抛出异常:任何Java方法中的代码都可以使用throw、throws抛出异常, 抛出异常表示自己并不处理异常,  而是把可能出现的异常抛给调用者去处理。
throws用在方法定于上,一旦方法使用了throws抛出某个异常时,那么调用者必须处理这个异常,如果调用者也不想处理这个异常,那么也必须往上将异常抛出,最终将有JVM来处理该异常,强烈建议不要交给JVM去处理:
4.png
这段代码在test方法中使用throws抛出了FileNotFoundException和IOException两个异常,而在main方法调用test方法时并没有try、catch去捕获这两个异常,也没有使用throws抛出,所以该程序将无法通过编译器编译,正确的做法应该:
6.png
当然,更推荐是在main方法中由我们自己来处理,而不是抛给JVM去处理:
7.png
除了上面使用throws在方法上抛出异常,有些时候我们需要在方法体里面根据需要抛出某个异常时,可以使用throw来操作。
throw用来抛出一个Throwable类型的异常,程序会在throw语句后立即终止,它后面的代码将不会执行,如:
8.png
该段代码在进入到if块后将执行throw new RuntimeException,当这段代码执行完后程序将终止,不再往后执行。
常见的异常有:
空指针异常类:NullPointerException
类型强制转换异常:ClassCastException
  数组负下标异常:NegativeArrayException
  数组下标越界异常:ArrayIndexOutOfBoundsException
  文件未找到异常:FileNotFoundException
  字符串转换为数字异常:NumberFormatException
  输入输出异常:IOException
方法未找到异常:NoSuchMethodException
小结:
1、不要将大块的代码放进try中,避免把不会出现异常的代码放到try块里面
2、避免异常的类型全部都写成Exception,应该细化异常类型
3、使用throws抛出异常时尽量自己处理,不要交给JVM来处理


0 个回复

您需要登录后才可以回帖 登录 | 加入黑马