后面会更新一个项目的经历,7月份入职的公司(新入职小菜鸟),和同事一起完成的一个完整的项目。异常在整个项目中也是非常重要的一部分,异常是业务异常还是系统系统,所以自己抽空看了一些异常相关的。
1异常定义:
异常也就是阻止程序正常执行的错误,如果不处理这个错误,程序会在异常的位置终止程序的执行,异常的作用就是让程序继续执行,但是并不是按照原来程序的流程执行,而是按照异常处理的流程处理。
2异常的类型
- 异常的父类Throwable,它包含两个子类,Error、Exception。
1)Error:也就是错误,是程序无法解决的错误,出现了Error类型的错误,虚拟机会自动终止程序。
2)Exception:程序可以处理的异常。 - Exception 类型
1)检查型异常:程序在编译期间就会被发现的异常,编辑器能够检查到的异常必须要用try{}catch语句进行捕获,否则程序编译不通过。IOException、SQLException
2)运行时异常:不能够在编译器件所被编译器发现的异常,运行时异常一般都是在程序的运行期间被发现的,通常都是程序的逻辑出现了问题。NullPointerException(空指针异常)、IndexOutOfBoundsException.
3)自定义异常和系统定义异常的区别:自定义异常在出现异常的时候,终究有一个位置要throw new 异常。系统异常在某个位置会throw这个异常,所以在printStachTrace() 方法中会打出异常的堆栈信息。
3异常处理机制
- 抛出异常:当某个方法中出现异常信息时,方法会创建异常对象,异常对象包含了异常的类型和异常出现时的程序的状态等异常信息。
- 捕获异常:从出现异常位置开始,首先保存当前栈帧(当前执行方法名称,参数类型,返回值等信息)也就是当前出现异常的位置,根据异常的类型去寻找程中相对应的异常处理程序。
- 一般异常处理过程:异常总是先被抛出后被捕捉的,当异常发生时,先去寻找合适的异常类型处理器,如果能够找到合适的异常处理器,就交给合适的异常处理器处理这个异常,当没有找到合适的异常处理器处理,就交给异常的父类Exception进行处理。所谓的处理异常就是try住这个可能出现异常的区域,然后catch这个异常,也就是捕获这个异常,紧接着通过printStachTrace()等方法打出堆栈信息。
- 运行时异常,即异常类型父类是RuntimeException类型的异常是不需要被捕获的,因为是程序内部自己定义类型的异常,如果出现了程序内部定义的异常,程序内存会进行处理。
示例程序:
public class Demo01 {
public static void main(String[] args) {
int[] intArray = new int[3];
try {
for (int i = 0; i <= intArray.length; i++) {
intArray[i] = i;
System.out.println("intArray[" + i + "] = " + intArray[i]);
System.out.println("intArray[" + i + "]模 " + (i - 2) + "的值: "
+ intArray[i] % (i - 2));
}
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("intArray数组下标越界异常。");
} catch (ArithmeticException e) {
System.out.println("除数为0异常。");
}
System.out.println("程序正常结束。");
}
程序结果
intArray[0] = 0
intArray[0]模 -2的值: 0
intArray[1] = 1
intArray[1]模 -1的值: 0
intArray[2] = 2
除数为0异常。
程序正常结束。
- 自定义异常的处理:try、catch的处理是正常的,但是在异常执行的过程中,需要throw new MyException(),否则程序的执行过程中不能够输出堆栈信息。自定义的需要需要自己处理异常。
定义异常
public class MyException extends Exception{
}
测试代码
public class MyTest {
public static void f() throws MyException{
throw new MyException();//抛出异常
}
public static void main(String[] args) {
try{
f();
}
catch (MyException e){
e.printStackTrace();
}
catch (NullPointerException ne){
ne.printStackTrace();
}
}
抛出异常,程序的的结果
com.demo.think.tij12.definition.MyException
at com.demo.think.tij12.definition.MyTest.f(MyTest.java:7)
at com.demo.think.tij12.definition.MyTest.main(MyTest.java:15)
不抛出异常,程序不会输出任何的结果。
异常的分析:出现了异常,程序还是会正常的执行,只不过走的是异常处理程序。程序的执行是通过操作栈来实现的,一个线程中所有的方法调用执行都是在一个栈内执行的。从main方法开始执行程序,一直到具体的Exception,1,2,3是程序的调用顺序,栈的特点是先进后出,所以通过printStachTrace()方法打印是从栈顶开始打印,一直到栈底!
4try catch finally执行顺序
- 对于可能出现异常的需要用try对该段代码进行捕获,然后用catch对异常进行捕获。无论是否抛出异常finally代码块都会被执行。
- 在一个try语句后面可能会出现了多个catch代码块,其中的一个catch代码块捕获到了异常,意味着整个try catch结束,不会在执行其他的代码块。
- finally代码不会被执行的几种情况:
1)在finally语句块中发生了异常。
2)在前面的代码中用了System.exit()退出程序。
3)程序所在的线程死亡。
4)关闭CPU。 - 异常执行顺序
1)当try没有捕获到异常时:try语句块中的语句逐一被执行,程序将跳过catch语句块,执行finally语句块和其后的语句;
2)当try捕获到异常,catch语句块里没有处理此异常的情况:当try语句块里的某条语句出现异常时,而没有处理此异常的catch语句块时,此异常将会抛给JVM处理,finally语句块里的语句还是会被执行,但finally语句块后的语句不会被执行;
3)当try捕获到异常,catch语句块里有处理此异常的情况:在try语句块中是按照顺序来执行的,当执行到某一条语句出现异常时,程序将跳到catch语句块,并与catch语句块逐一匹配,找到与之对应的处理程序,其他的catch语句块将不会被执行,而try语句块中,出现异常之后的语句也不会被执行,catch语句块执行完后,执行finally语句块里的语句,最后执行finally语句块后的语句;
参照博客:http://blog.csdn.net/hguisu/article/details/6155636
参照书籍:java编程思想