Java异常概述

在使用计算机语言进行项目开发的过程中,即使程序员把代码写得尽善尽美,在系统的运行过程中仍然会遇到一些问题,因为很多问题不是靠代码能够避免的,比如:客户输入数据的格式,读取文件是否存在,网络是否始终保持通畅等等。

在Java语言中,将程序执行中发生的不正常情况称为“异常”。异常是程序中的一些错误,但并不是所有的错误都是异常,并且错误有时候是可以避免的。

程序在运行时出现的不正常情况,其实就是程序中出现的问题。这个问题按照面向对象思想进行描述,并封装成了对象。因为问题的产生有产生的原因、有问题的名称、有问题的描述等多个属性信息存在。当出现多属性信息最方便的方式就是将这些信息进行封装。异常就是java按照面向对象的思想将问题进行对象封装,这样就方便于操作问题以及处理问题。

 

Java异常处理机制的优点:

1)Java通过面向对象的方法进行异常处理,把各种异常事件进行分类,体现了良好的层次性,提供了良好的接口,这种机制对于具有动态特性的复杂提供了强有力的控制方式。 

2)Java的异常处理机制使得处理异常的代码和“常规”代码分开,减少了代码的数量,增强了程序的可读性。 

3)由于把异常当成事件处理,利用类的层次性我们可以把多个具有相同父类的异常统一处理,也可以区分不同的异常分别处理,使用非常灵活。

 

异常分类

Java异常概述

由图可知Java程序在执行过程中所发生的异常事件可分为两类:

Error(错误): 

Java虚拟机无法解决的严重问题。表示应用程序运行时出现的重大错误。如:JVM系统内部错误、Socket编程时出现的端口占用、资源耗尽等严重情况。一般不编写针对性的代码进行处理。

Exception(异常):

其它因编程错误或偶然的外在因素导致的一般性问题,可以使用针对性的代码进行处理。例如:

        1)空指针访问      2)试图读取不存在的文件       3)网络连接中断

无论是错误还是异常,它们都有具体的子类体现每一个问题,它们的子类都有一个共性,就是都以父类名才作为子类的后缀名。

对于这些错误,一般有两种解决方法:一是遇到错误就终止程序的运行。另一种方法是由程序员在编写程序时,就考虑到错误的检测、错误消息的提示,以及错误的处理。捕获错误最理想的是在编译期间,但有的错误只有在运行时才会发生。比如:除数为0,数组下标越界等。

 

错误分类:

Error类与异常一样,它们都是继承自java.lang.Throwable类。Error 类对象由 Java 虚拟机生成并抛出。Error类包括linkageError(结合错误)与VitualmachineError(虚拟机错误)两种子类。  

结合错误

LinkageError LinkageError 的子类表示一个类依赖于另一个类,但是, 在前一个类编译之后, 后一个类的改变会与它不兼容。
ClassFormarErro 类格式所产生的错误。
ClassCircularityError 无限循所产生的错误。
ExceptionInInitializerError 初始化所产生的错误。
NoClassDeFormatError 没有类定义所产生的错误。
VeritfyError 类文件某些数据不一致或安全问题所产生的错误。
UnsatisfidLinkError Java虚拟机无法找到合适的原始语言(native-language)定义的方法所产生的错误。
IncompatibleClassChangeError 不兼容类所产生的错误。
AbtractMethodError 调用抽象方法所产生的错误。
NoSuchFieldError 存取或改变数据域所产生的错误。
IllegalAccessError 不合法存取或改变数据域或调用方法所产生的错误。
InstantionError 使用抽象类或接口所产生的错误。

虚拟机错误

当Java虚拟机崩溃了或用尽了它继续操作所需的资源时,抛出该错误。     

InternalError 虚拟机内部所产生的错误。
OutOfMemoryError 虚拟机内存不足所产生的错误。     
*Error 堆栈无法容纳所产生的错误。
UnknownError 虚拟机不知名异常所产生的错误。

 

异常分类

运行时异常

是指编译器不要求强制处置的异常。一般是指编程时的逻辑错误,是程序员应该积极避免其出现的异常。java.lang.RuntimeException类及它的子类都是运行时异常。

对于这类异常,可以不作处理,由Java默认异常处理机制来处理。因为这类异常很普遍,若全处理可能会对程序的可读性和运行效率产生影响。

常见的运行时异常:

ArithmeticException 当出现异常的运算条件时,抛出此异常。例如,一个整数"除以零"时,抛出此类的一个实例。
ArrayIndexOutOfBoundsException 用非法索引访问数组时抛出的异常。如果索引为负或大于等于数组大小,则该索引为非法索引。
ArrayStoreException 试图将错误类型的对象存储到一个对象数组时抛出的异常。
ClassCastException 当试图将对象强制转换为不是实例的子类时,抛出该异常。
IllegalArgumentException 抛出的异常表明向方法传递了一个不合法或不正确的参数。
IllegalMonitorStateException 抛出的异常表明某一线程已经试图等待对象的监视器,或者试图通知其他正在等待对象的监视器而本身没有指定监视器的线程。
IllegalStateException 在非法或不适当的时间调用方法时产生的信号。换句话说,即 Java 环境或 Java 应用程序没有处于请求操作所要求的适当状态下。
IllegalThreadStateException 线程没有处于请求操作所要求的适当状态时抛出的异常。
IndexOutOfBoundsException 指示某排序索引(例如对数组、字符串或向量的排序)超出范围时抛出。
NegativeArraySizeException 如果应用程序试图创建大小为负的数组,则抛出该异常。
NullPointerException 当应用程序试图在需要对象的地方使用 null 时,抛出该异常
NumberFormatException 当应用程序试图将字符串转换成一种数值类型,但该字符串不能转换为适当格式时,抛出该异常。
SecurityException 由安全管理器抛出的异常,指示存在安全侵犯。
StringIndexOutOfBoundsException 此异常由 String 方法抛出,指示索引或者为负,或者超出字符串的大小。
UnsupportedOperationException 当不支持请求的操作时,抛出该异常。

编译时异常

是指编译器要求必须处置的异常。即程序在运行时由于外界因素造成的一般性异常。编译器要求java程序必须捕获或声明所有编译时异常。

对于这类异常,如果程序不处理,可能会带来意想不到的结果。

常见的编译时异常:

ClassNotFoundException 应用程序试图加载类时,找不到相应的类,抛出该异常。
CloneNotSupportedException 当调用 Object 类中的 clone 方法克隆对象,但该对象的类无法实现 Cloneable 接口时,抛出该异常。
IllegalAccessException 拒绝访问一个类的时候,抛出该异常。
InstantiationException 当试图使用 Class 类中的 newInstance 方法创建一个类的实例,而指定的类对象因为是一个接口或是一个抽象类而无法实例化时,抛出该异常。
InterruptedException 一个线程被另一个线程中断,抛出该异常。
NoSuchFieldException 请求的变量不存在
NoSuchMethodException 请求的方法不存在

编译时被检查的异常和运行时异常的区别:

编译被检查的异常在方法内被抛出,方法必须要声明,否编译失败。声明的原因:是需要调用者对该异常进行处理。

运行时异常如果在方法内被抛出,在方法上不需要声明。不声明的原因:不需要调用者处理,运行时异常发生,已经无法再让程序继续运行,所以,不让调用处理的,直接让程序停止,由调用者对代码进行修正。

 

异常方法

下面的列表是 Throwable 类的主要方法:

1 public String getMessage()
返回关于发生的异常的详细信息。这个消息在Throwable 类的构造函数中初始化了。
2 public Throwable getCause()
返回一个Throwable 对象代表异常原因。
3 public String toString()
使用getMessage()的结果返回类的串级名字。
4 public void printStackTrace()
打印toString()结果和栈层次到System.err,即错误输出流。
5 public StackTraceElement [] getStackTrace()
返回一个包含堆栈层次的数组。下标为0的元素代表栈顶,最后一个元素代表方法调用堆栈的栈底。
6 public Throwable fillInStackTrace()
用当前的调用栈层次填充Throwable 对象栈层次,添加到栈层次任何先前信息中。