java异常处理机制

来源:互联网 发布:网络打印机文档被挂起 编辑:程序博客网 时间:2024/05/21 11:34


引言:

在C语言时代,程序处理错误的方式主要是通过判断函数返回值来处理的。采用这种方式要求每次调用函数都必须对返回值进行判断,并采取相应的处理措施,无疑给程序员带来了很大的工作量。所以,现实中程序员往往直接不对返回值采取错误检测。

相对C而言,C++,Java都采用了所谓的异常处理机制来实现错误处理,当然C++为了向后兼容,代码中往往还会出现通过返回值进行错误处理的情况。

什么是异常处理机制:

异常处理机制,目的就是将错误产生的地方跟处理错误的地方分离开来,从而避免因为在有可能产生错误的代码中加入过多的错误检测,影响程序本身的执行逻辑。

java异常类层次结构图:



Throwable: 有两个重要的子类:Exception(异常)和 Error(错误),二者都是 Java 异常处理的重要子类,各自都包含大量子类。

Error(错误):是程序无法处理的错误,表示运行应用程序中较严重问题。大多数错误与代码编写者执行的操作无关,而表示代码运行时 JVM(Java 虚拟机)出现的问题。例如,Java虚拟机运行错误(Virtual MachineError),当 JVM 不再有继续执行操作所需的内存资源时,将出现 OutOfMemoryError。这些异常发生时,Java虚拟机(JVM)一般会选择线程终止。这些错误表示故障发生于虚拟机自身、或者发生在虚拟机试图执行应用时,如Java虚拟机运行错误(Virtual MachineError)、类定义错误(NoClassDefFoundError)等。这些错误是不可查的,因为它们在应用程序的控制和处理能力之 外,而且绝大多数是程序运行时不允许出现的状况。对于设计合理的应用程序来说,即使确实发生了错误,本质上也不应该试图去处理它所引起的异常状况。在 Java中,错误通过Error的子类描述。

Exception(异常):是程序本身可以处理的异常。Exception 类有一个重要的子类 RuntimeException。RuntimeException 类及其子类表示“JVM 常用操作”引发的错误。例如,若试图使用空值对象引用、除数为零或数组越界,则分别引发运行时异常(NullPointerException、ArithmeticException)和 ArrayIndexOutOfBoundException。

这里我么主要探讨运行时异常和非运行时异常

非运行时异常

RuntimeException以外的异常,类型上都属于Exception类及其子类。从程序语法角度讲是必须进行处理的异常,如果不处理,程序就不能编译通过。如IOException、SQLException等以及用户自定义的Exception异常

eg:

class Demo{int div(int a,int b) throws Exception{return a/b;}}class ExceptionDemo{public static void main(String[] args){Demo d = new Demo();System.out.println(d.div(4,0));}}


运行时异常

运行时异常在编译过程中不会出现异常报错,在运行时才出现异常报错

eg:

class Demo{int div(int a,int b){if(b == 0)throw new ArithmeticException("被零整除");return a/b;}}class ExceptionDemo{public static void main(String[] args){Demo d = new Demo();System.out.println(d.div(4,0));}}

运行结果中看到虽然函数内抛出了异常但是在函数上没有声明异常,结果能通过编译但是运行时报错:这是应为ArithmeticException是一个运行时异常

而如果换个非运行是异常又会有什么不同呢?

eg:

class Demo{int div(int a,int b){if(b == 0)throw new Exception("被零整除");return a/b;}}class ExceptionDemo{public static void main(String[] args){Demo d = new Demo();System.out.println(d.div(4,0));}}

可以看到如果抛出的不是运行时异常编译是不能通过的。

运行时异常被声明了可以不被捕捉也可以通过编译

eg:

class Demo{int div(int a,int b) throws ArithmeticException{return a/b;}}class ExceptionDemo{public static void main(String[] args){Demo d = new Demo();System.out.println(d.div(4,0));}}


运行结果可以看出,编译通过,运行时报告异常报告

而非运行时异常如果抛出了异常,就必须对异常处理才能通过编译

自定义异常:

自定义异常首先要继承已有的异常类比如:RuntimeException,Exception....

eg:自定义一个负数为除数时显示异常:

class FuShuException extends Exception{FuShuException(String msg){super(msg);}}class Exception_Mine{int div(int a,int b) throws FuShuException{if(b<0)throw new FuShuException("..... /by fushu");//手动通过throw抛出异常elsereturn a/b;}}class ExceptionMine{public static void main(String[] args){Exception_Mine em = new Exception_Mine();try{System.out.println(em.div(3,-1));}catch(FuShuException e){System.out.println(e.toString());}}}


异常处理机制:

java异常处理机制为:抛出异常和捕捉异常

抛出异常:

当一个方法可能会出现一些错误时,我们为了防止调用者调用是恰好用的了可能不错的情况时,我们不让其通过编译除非其处理可能发生的异常

eg:

class Demo{int div(int a,int b) throws{if(b == 0)throw new Exception("被零整除");return a/b;}}class ExceptionDemo{public static void main(String[] args){Demo d = new Demo();try{System.out.println(d.div(4,0));}catch(Exception e){System.out.println(e.toString());}}}

捕获异常:

当要调用一个方法而这个方法声明了一个异常的时候我们就必须要处理这个异常这个处理异常的过程就是捕获异常

eg:div方法有一个异常

<span style="white-space:pre"></span>try{System.out.println(d.div(4,0));}catch(Exception e){System.out.println(e.toString());}

throws和throw

throw和throws的区别

throws使用在函数上

格式:

int div(int a,int b) throws FuShuException
throw使用在函数内

格式:

if(b<0)throw new FuShuException("by fushu");
throws后面跟的是异常类。可以跟多个,用逗号隔开

throw后面跟的是异常对象

异常处理语句语法规则:

1)  必须在 try 之后添加 catch 或 finally 块。try 块后可同时接 catch 和 finally 块,但至少有一个块。

2) 必须遵循块顺序:若代码同时使用 catch 和 finally 块,则必须将 catch 块放在 try 块之后。

3) catch 块与相应的异常类的类型相关。

4) 一个 try 块可能有多个 catch 块。若如此,则执行第一个匹配块。即Java虚拟机会把实际抛出的异常对象依次和各个catch代码块声明的异常类型匹配,如果异常对象为某个异常类型或其子类的实例,就执行这个catch代码块,不会再执行其他的 catch代码块

5) 可嵌套 try-catch-finally 结构。

6) 在 try-catch-finally 结构中,可重新抛出异常

try catch final执行顺序:

1)当try没有捕获到异常时:try语句块中的语句逐一被执行,程序将跳过catch语句块,执行finally语句块和其后的语句;

2)当try捕获到异常,catch语句块里没有处理此异常的情况:当try语句块里的某条语句出现异常时,而没有处理此异常的catch语句块时,此异常将会抛给JVM处理,finally语句块里的语句还是会被执行,但finally语句块后的语句不会被执行;

3)当try捕获到异常,catch语句块里有处理此异常的情况:在try语句块中是按照顺序来执行的,当执行到某一条语句出现异常时,程序将跳到catch语句块,并与catch语句块逐一匹配,找到与之对应的处理程序,其他的catch语句块将不会被执行,而try

句块中,出现异常之后的语句也不会被执行,catch语句块执行完后,执行finally语句块里的语句,最后执行finally语句块后的语句;

0 0