什么是异常?
异常就是不可预测的不正常情况。比如你出门被人打,走路掉坑里等...在程序中异常就是程序出现了bug,而导致程序无法按我们的指令办事。Java采用了 一种面向对象的机制,即把异常看作一种类型,每当发生这种事件时,Java就自动创建一个异常对象,并执行相应的代码去处理该事件。在java当中异常一共分为两种:一种是
Exception
,另一种则是
Error
。而Exception下面又分两类,一种是编译时异常(
CheckedException
),一种则是运行时异常(
RuntimeException
),一般的来说Exception异常是可以进行捕获的,比如io,空指针,数组越界等。而Error异常不可以捕获,一般是内存溢出等。
本文主要是try-catch的一个学习,在Java 中的异常处理都是围绕着 try-catch-finally, throw, throws 这几3种展开的
- try-catch-finally:捕获异常并处理。
- throw:遇到错误的时候抛出一个异常。
- throws:声明一个方法可能抛出的异常(所有可能抛出的异常都需要声明)
1.下面是异常的3种基本格式:
try {
程序执行体 (会出错的代码)
}catch (小异常类型1 异常对象1) {
异常处理程序体1
}finally{
异常处理结束前的执行程序体,无论最后结果如何都会执行这里面的代码
}
2.异常中的catch也可以写多个:
try {
程序执行体 (会出错的代码)
}catch (小异常类型1 异常对象1) {
异常处理程序体1
}catch (比前面大的异常类型2 异常对象2) { //catch可以有多个
异常处理程序体2
}finally{
异常处理结束前的执行程序体,无论最后结果如何都会执行这里面的代码
}
3.异常中的finally可省略写(具体看业务需求):
try {
程序执行体 (会出错的代码)
}catch (小异常类型1 异常对象1) {
异常处理程序体1
}
4.异常中的catch也可省略写(但后面一定要加上finally)
try {
程序执行体 (会出错的代码)
}finally{
异常处理结束前的执行程序体,无论最后结果如何都会执行这里面的代码
}
- try{}:一般用来监视有可能产生异常的代码部分;
- catch(异常类型 异常对象){}:当异常产生后,catch块捕捉异常,并在其中对异常进行处理。
- finally{}:无论try/catch块中发生了什么,finally块都一定会执行。它也可选的(在不需要的时 候可以省略不写),可视具体情况决定是否添加。它一般运用在当异常发生时,程序可能会意外 中断,有些被占用的资源就得不到清理。finally块可以确保执行所有的清理工作,例如是最经典 的io流的关流,jdbc连接的关闭。注:finally块必须和try块一起使用,不能单独存在。
try-catch-finally的执行流程:
1.程序出现Bug:
假设程序出现的bug,这种异常处理它会先在try块
捕获到异常,然后再进入到catch块,进行异常的一个处理,如果有多个catch块的话,它会依次从上往下执行(
小异常写在前面,大异常写在后面,否则报错),直到能处理这种异常的catch块才会停止下来,最后进入finally块(finally块一定会进)。
顺序:
try-->catch...-->finally
2.程序未出现Bug:
如果程序没有出现bug,它还是会在try进行异常的
捕获,没有异常出现,它也没必要进入catch块进行异常的处理。它会直接进入到finally块。
顺序:
try-->finally
嵌套try/catch块:
有时候,整个语句块可以产生异常,而其中的某个部分又可能产生另外的异常,而我们需要分别进行处理。这样,就可以通过嵌套try/catch块来完成(嵌套try/catch块就是在一个try/catch块中包含有另外的try/catch块)。
例如:
package com.java.exception;
/**
* 嵌套try/catch块
* ExceptionDemo2
* 创建人:罗祥
* 时间:2018年4月1日-下午12:26:40
* @version 1.0.0
*
*/
public class ExceptionDemo2 {
public static void main(String[] args) {
/*外层try/catch块*/
try {
System.out.println("传递的参数是:" + args[0]);
/*嵌套try/catch块*/
try {
int num = Integer.parseInt(args[0]);
System.out.println(num + "的平方是" + (num * num));
} catch (NumberFormatException nfe) {
System.out.println("您输入的不是数字。");
}
}
catch (ArrayIndexOutOfBoundsException aioobe) {
System.out.println("您没有输入命令行参数。");
}
}
}
上述的代码当中,第一层
捕获代码是否
用非法索引访问数组时抛出的异常,也就是常见的数组下标越界。第二层则是数字格式化异常。因为这两个地方可能会出现异常,但也可能不出现异常,最好都处理一下,保持程序的健壮性。