java异常处理优点_Java 异常

1. 异常

1.1 异常概念

概念:指的是程序在执行过程中,出现的非正常的情况,最终导致JVM的非正常停止。

在Java的面向对象的编程语言中,异常本身就是一个类,产生异常就是创建异常对象并抛出一个异常对象。Java处理异常的方式是中断处理。

方法调用流程:

Java虚拟机用方法调用栈(method invocation stack)来跟踪每个线程中一系列的方法调用过程。该堆栈保存了每个调用方法的本地信息(比如方法的局部变量)。每个线程都有一个独立的方法调用栈。对于Java应用程序的主线程,堆栈底部是程序的入口方法main()。当一个新方法被调用时,Java虚拟机把描述该方法的栈结构置入栈顶,位于栈顶的方法为正在执行的方法。

当一个方法正常执行完毕,Java虚拟机会从调用栈中弹出该方法的栈结构,然后继续处理前一个方法。如果在执行方法的过程中抛出异常,则Java虚拟机必须找到能捕获该异常的catch代码块。它首先查看当前方法是否存在这样的catch代码块,如果存在,那么就执行该catch代码块;否则,Java虚拟机会从调用栈中弹出该方法的栈结构,继续到前一个方法中查找合适的catch代码块。在回溯过程中,如果Java虚拟机在某个方法中找到了处理该异常的代码块,则该方法的栈结构将成为栈顶元素,程序流程将转到该方法的异常处理代码部分继续执行。当Java虚拟机追溯到调用栈的底部的方法时,如果仍然没有找到处理该异常的代码块,按以下步骤处理。

(1)调用异常对象的printStackTrace()方法,打印来自方法调用栈的异常信息。

(2)如果该线程不是主线程,那么终止这个线程,其他线程继续正常运行。如果该线程是主线程(即方法调用栈的底部为main()方法),那么整个应用程序被终止。

异常处理机制的优点

在一些传统的编程语言,如C语言中,并没有专门处理异常的机制,程序员通常用方法的特定返回值来表示异常情况,并且程序的正常流程和异常流程都采用同样的流程控制语句。

Java语言按照面向对象的思想来处理异常,使得程序具有更好的可维护性。Java异常处理机制具有一下优点:

(1)把各种不同类型的异常情况进行分类,用Java类来表示异常情况,这种类被称为异常类。把异常情况表示成异常类,可以充分发挥类的可扩展和可重用的优势。

(2)异常流程的代码和正常流程的代码分离,提高了程序的可读性,简化了程序的结构。

(3)可以灵活的处理异常,如果当前方法有能力处理异常,就捕获并处理它,否则只需要抛出异常,由方法调用者来处理它。

1.2 异常体系

异常的根类:java.lang.Throwable,其中的两个子类:java.lang.Error 与 java.lang.Exception。

java异常处理优点_Java 异常_第1张图片

(1)Throwable体系:

Error:无法通过处理的错误,只能事先避免。

Exception:表示异常,产生的异常程序员可以通过代码纠正,使程序继续运行,是必须要处理的。

(2)Throwable中常用方法:

public void printStackTrace() : 打印异常详细信息(包含了异常类型,异常原因,还包括异常出现的位置)。

public String getMessage(): 获取发生异常的原因(提示给用户的时候,就提示错误原因)。

public String toString(): 获取异常的类型和异常描述信息(不常用)。

1.3 异常分类

(1)受检异常:

checked exception。是程序执行期间发生的严重事件的后果。

例如,如果程序想从磁盘读入数据,而系统找不到含有数据的文件,将会发生受检异常。

受检异常的所有类都是类 Exception 的子类。

Java 类库中的下列类表示受检异常:ClassNotFoundException、FileNotFoundException、IOException、NoSuchMethodException 及 WriteAbortedException。

(2)运行时异常:

runtime异常。通常是程序中逻辑错误的结果。

运行时异常的所有类都是类 RuntimeException 的子类,它是 Exception 的后代。

Java 类库中的下列类表示运行时异常:ArithmeticException、ArrayIndexOutOfBoundsException、ClassCastException等。

(3)错误:

错误(error)是标准类 Error 或其后代类的一个对象,这样的类都成为错误类(errorclass)。

Error 是 Throwable 的后代。

一般的,错误是指发生了不正确的情况,如内存溢出。

2. 异常处理

2.1 try-catch 块

因为有输入操作而可能要处理 IOException 异常的代码段有如下形式:

try

{

//

anObject.readString(···); //可能抛出一个 IOException

//

}

catch (IOException e)

{

//< 响应异常代码,可能含有下面这行:>

System.out.println(e.getMessage());

}

如果没有发生异常,则 try 块内的语句全部执行,然后执行 catch 块后的语句。如果在 try 块内发生了 IOException,则执行立即转到 catch 块。此时已经捕获了异常。

作为一个对象,每个异常都有存取方法 getMessage(),它返回抛出异常时创建的描述字符串。

在一个 try 块语句中,可能会抛出不同类型异常中的任意一个。在这样的 try 块后的 catch 块需要能捕获多个类的异常。为此可以在 try 块后写多个 catch 块。所以 catch 块出现的次序很重要。程序的执行流程进入到其参数与异常的类型相匹配的第一个 catch 块————按照出现的次序。

例如,下列 catch 块的次序不好,因为 FileNotFoundException 的 catch 块永远不会执行:

catch (IOException e)

{

···

}

catch (FileNotFoundException e)

{

···

}

按照这个次序,任何 I/O异常 都将被第一个 catch 块所捕获。因为 FileNotFoundException 派生于 IOException。

2.2 finally 语句

不论是否捕获到异常,总要执行 finally 后面的语句。一般地,为了统一处理程序出口,可将需公共处理的内容放到 finally 后的代码段中。

示例:

try {

startFaucet();

waterlawn();

} finally {

stopFaucet();

}

stopFaucet() 方法总被执行。try 后花括号中的代码成为保护代码。如果在保护代码内执行了 System.exit() 方法,将不执行 finally 后面的语句。

2.3 公共异常

(1)ArithmeticException

整数除法中,如果除数为 0 ,则发生该类异常,例如:

int i = 12 /0;

(2)NullPointerException

如果一个对象还没有实例化,那么访问该对象或调用它的方法将导致 NullPointerException 异常。例如:

image im [] = new image [4];

System.out.println(im[0].toString());

第一行创建了有 4 个元素的数组 im,每个元素都是 image 类型,系统为其进行初始化每个元素中的值为 null,表明它还没有指向任何实例。第二行要访问 im[0],由于访问的是还没有进行实例化的空引用,因此导致 NullPointerException 异常。

(3)NegativeArraySizeException

按常规,数组的元素个数应该是一个大于等于 0 的整数。创建数组时,如果元素个数是个负数,则会引发 NegativeArraySizeException 异常。

(4)ArrayIndexOutOfBoundsException

Java 把数组看作是对象,并用 length 变量记录数组的大小。访问数组元素时,运行时环境根据 length 值检查下表的大小。如果数组下标越界,则将导致 ArrayIndexOutOfBoundsException 异常。

(5)SecurityException

该类异常一般在浏览器内抛出。若 Applet 试图进行下述操作,则由 SecurityManager 类抛出此异常:

打开本地文件。

打开一个套接口,而不是返回到提供 Applet 的主机。

在运行时环境中运行另一个程序。

(6)ArrayStoreException

程序试图存取数组中错误的数据类型。

(7)FileNotFoundException

试图存取一个并不存在的文件。

(8)IOException

该异常是指通常的 I/O 错误。

3. 抛出异常

当程序员不在当前方法内处理异常,而是把异常抛出到调用方法中。在不能使用合理的方式解决不正常或意外事件的情形下,才抛出异常。

方法内执行 throw 语句时,需要创建一个对象,才会抛出一个异常。一般的形式是:

throw new IOException();

在说明方法时,具体格式如下:

(参数列表) throws 异常列表

紧接在关键字 throws 后面的是该方法内可能发生且不进行处理的所有异常列表。各异常之间以逗号分隔。

如果方法内含有一个抛出异常的 throw 语句,则在方法头需要添加一个 throws 子句,而不是在方法体内捕获异常。一般地,抛出异常及捕获异常应该在不同的方法内。在方法头中用 Java 保留字 throws 声明这个方法可能抛出的异常。在方法体中用 throw 抛出一个异常。

你可能感兴趣的:(java异常处理优点)