首页 > 代码库 > Java异常处理

Java异常处理

一、概述

        如果一个人生病了,我们就要对其诊断,然后对症下药,否则任其病不断发展下去或是多种病同时存在,这个人就会变得痛苦,不能正常工作。同样,java是在网络中运行的,为了保证运行安全,网络能正常的运转,同样需要找出程序运行时的错误,并能够及时有效的进行处理,则java引出了异常。所谓异常既是不同于正常的,那么我们也可以称其为例外。

二、异常框架

       异常处理在程序设计时非常重要,是程序设计的一个难点,在我们学习C++时,同一个异常或者错误如果多个地方出现,那么我们必须每个地方都要做相同处理,感觉相当麻烦。Java语言设计时就考虑这个问题,提出异常处理框架,所有的异常都可以用一个类型来表示,不同类型的异常对应不同的子类异常,定义了异常处理规范。在1.4版本以后增加了异常链机制,从而便于跟踪异常。

Throwable是类库java.lang包中的一个类,它派生了两个子类:Error和Exception。

Throwable是可被抛出的,只要任何继承它的类都可以抛出。

1、Error:系统内部错误,是程序无法处理的错误。

       它表示运行应用程序时较严重的问题。大多数错误与代码编写执行者的操作无关,这些错误是不可查的,他们在应用程序的控制和处理能力之外,而表示代码运行时JVM出现的问题。例如:java虚拟机运行错误、当JVM不再有继续执行操作所需要的内存资源时,将出现OutOfMemoryError。这些异常发生错误时,Java虚拟机一般会选择终止线程。

2、Exception:程序本身可以处理的异常。

Exception包括:运行时异常错误和非运行时异常(编译异常)。

(1)运行时异常(可查异常):Java编译器不检查它,也就是说,当程序中可能出现这类异常,即使没有用try-catch语句捕获它,也没有用throws子句声明抛出它,也会编译通过。包括RuntimeException及其子类。这些异常一般是程序逻辑错误引起的,程序应该从逻辑角度尽可能避免这类异常的发生。

(2)非运行时异常(不可查异常): Java编译器会检查它,也就是说,当程序中可能出现这类异常,要用try-catch语句捕获它,或用throws子句声明抛出它,否则编译不通过。包括除RuntimeException以外的其它类。

补充:可查异常即编译器要求必须处置的异常:不可查异常即编译器不要求强制处置的异常,它还包括错误(Error)。

Exception同其他类一样,有自己的属性和方法,了解它有利于我们更好的用户自定义异常类。

它的两个构造函数是

Public Exception();

Public Exception(String s);

它的常用方法是

Public StringtoString()//这个方法用来给出详细的错误信息

Public voidprintStackTrace()//打印出当前异常对象的堆栈使用轨迹,即程序先后执行了那些对象或类的方法,才使得运行过程中产生了这个异常对象。

小结:错误和异常的最主要区别:异常可被程序本身处理,错误不可以。

三、定义异常

1、 系统定义的运行异常:是系统事先定义好并包装在java类库中的。它通常对应着系统运行错误,这种错误很可能导致操作系统错误,甚至整个系统的瘫痪,所以要定义特别类来进行处理。常见的系统定义异常可参见http://soft.chinabyte.com/database/491/12129991.shtml这个网址,这位博主整理的不错。

2、 用户自定义的异常:是编程人员根据程序的特殊逻辑在用户程序里自己创建用户自定义的异常类和异常对象。这种用户自定义异常主要用来处理用户程序中特定的逻辑运行错误。

下面定义的是队列类的一个出队方法,这个仅是代码一部分:

class Queue
{
	int dequeue ()  //减队操作,若队列不空,则从队列头部取出一个数据
	{
	    int data ;
		if(!isEmpty()){
		    data = http://www.mamicode.com/First.getData();>

        在这个方法里,如果队列已经为空,则此方法给出一个数据“-1”表示出队的操作失败,这样处理的坏处是对垒不能保存“-1”这个数据,同时还要求其他调用dequeue的方法了解这个异常的约定,显然对程序的调试和运行都不方便,为解决这个问题,可以定义一个程序异常EmptyQueueException,专门处理“从空队列中出队”的逻辑错误。

class EmptyQueueException extends Exception     //用户自定义的系统类的子类
{
	Queue queue;
    public EmptyQueueException(Queue q){
	    super("队列已空!");
		queue = q;
	}

	public String toString(){         //重载父类的方法,给出详细的错误信息       
	    return ("队列" + queue.toString() + "已经为空,执行出队操作引发异常!");
	}
}

四、抛出异常

Java程序在运行时如果引发了一个可以识别的错误,就会产生一个与该错误对应的异常类对象,这个过程被称为异常的抛出。

1、 系统自动抛出的异常:系统定义的异常都可以由系统自动抛出。如:以零为除数时出现的算数异常。

2、 语句抛出的异常

用户自定义的异常不能依靠系统抛出,必须借助throw语句。并应该抛出这个异常类的新对象如果抛出的是Exception异常类型,则该方法被声明为抛出所有的异常。多个异常可使用逗号分割。throws语句的语法格式为:

methodname throws Exception1,Exception2,..,ExceptionN
 {   …
    Thrownew 异常类名;
    …
 } ;

以下代码展示我们怎样抛出上面的queue()方法可能抛出EmptyQueueExpection异常对象

class Queue
{
	int dequeue () throws EmptyQueneException  //减队操作,若队列不空,则从队列头部取出一个数据
	{
	    int data ;
		if(!isEmpty()){
		    data = http://www.mamicode.com/First.getData();>

抛出异常注意事项:

1、 重写方法需要抛出与原方法所抛出异常类型一致或者不抛出异常;

2、 必须声明方法可抛出的任何可查异常(checked exception)。即如果一个方法可能出现受可查异常,要么用try-catch语句捕获,要么用throws子句声明将它抛出,否则会导致编译错误

3、 在编程中不能在main中抛出异常,要进行处理在main方法中

五、异常处理

当我们抛出异常的时候,要进行异常的处理。异常处理主要包括捕捉异常、程序流程的跳转和异常处理语句块的定义。

异常处理的格式:

Try{
   //可能会发生异常的程序代码
}
Catch{
  //捕获并处理try抛出的异常类型,可以有多个catch语句
}
Finally{
  //对程序的状态做统一的处理
}

针对上面的例子,做异常处理,代码如下:

public class test
{
	public static void main(String args[]){
	   Queue queue = new Queue();

	   for ( ing i=1;i<8;i++ )
	   {
		   queue.enqueue(i);   //调用Queue的入队函数
		   System.out.println(queue.visitAllNode()); //显示队列中的内容
	   }

	   try
	   {
		  while (!queue.isEmpty())   //调用出队函数
		  {
			  System.out.print(queue.dequeue()+"出队");
              System.out.print("队列中还有" + queue.visitAllNode());
		  }
	   }
	   catch ( EmptyQueueException eqe)
	   {
		   System.out.println(eqe.toString());
	   }
	}
}

       针对多异常的处理,是定义若干个块来实现的,每个块用来接收和处理一种特定的异常对象,并且异常类型小的放前,大的放后,经常出错的放前,不经常出错的放后面,因为catch是按先后顺序排列的。如果所有的catch块与不能与当前的异常对象匹配,则说明当前方法不能处理这个异常对象,程序流将返回到调用该方法的上层方法,如果这个上层方法中定义了与所产生的异常对象相匹配的catch块,流程就转到这个catch中;否则继续回溯,如下图展示情况:

  

异常处理的原则:

1、避免过大的try块,不要把不会出现异常的代码放到try块里面,尽量保持一个try块对应一个或多个异常。

2、细化异常的类型,不要不管什么类型的异常都写成Excetpion。

3、catch块尽量保持一个块捕获一类异常,不要忽略捕获的异常,捕获到后要么处理,要么转译,要么重新抛出新类型的异常。

4、不要用try...catch参与控制程序流程,异常控制的根本目的是处理程序的非正常情况。

六、总结

         总之,程序执行时经常会出现除零溢出、数组越界等运行错误,影响程序的正常执行。错误及异常是不可避免的,一个好的应用程序,在满足用户要求的各种功能的同时,还应具备能预见程序执行过程中可能产生的各种异常的能力,并能为异常情况给予恰当处理。Java语言通过面向对象的异常处理机制来解决运行期间的错误,可以预防错误的程序代码或系统错误所造成的不可预期的结果发生。减少编程人员的工作,增加了程序的灵活性,增加程序的可读性和健壮性。