异常操作

异常操作

捕获异常

使用trycatch关键字可以捕获异常。try/catch代码块放在异常可能发生的地方。try/catch代码块中的代码称为保护代码,使用try/catch的语法如下:

try
{
   // 程序代码
}catch(ExceptionName e1)
{
   //Catch 块
}

Catch语句包含要捕获异常类型的声明。当保护代码块中发生一个异常时,try后面的catch块就会被检查。如果发生的异常包含在catch块中,异常会被传递到该catch块,这和传递一个参数到方法是一样。

譬如下面的例子中声明有两个元素的一个数组,当代码试图访问数组的第三个元素的时候就会抛出一个异常。

// 文件名 : ExcepTest.java
import java.io.*;
public class ExcepTest{

   public static void main(String args[]){
      try{
         int a[] = new int[2];
         System.out.println("Access element three :" + a[3]);
      }catch(ArrayIndexOutOfBoundsException e){
         System.out.println("Exception thrown  :" + e);
      }
      System.out.println("Out of the block");
   }
}

/**
Exception thrown  :java.lang.ArrayIndexOutOfBoundsException: 3
Out of the block
**/

对于异常的捕获不应该觉得方便而将几个异常合成一个Exception进行捕获,比如有IO的异常跟SQL的异常,这样完全不同的两个异常应该分开处理!而且在catch里处理异常的时候不要简单的e.printStackTrace(),而是应该进行详细的处理。比如进行console打印详情或者进行日志记录。

多重捕获块

一个try代码块后面跟随多个catch代码块的情况就叫多重捕获。多重捕获块的语法如下所示:

try{
   // 程序代码
}catch(异常类型1 异常的变量名1){
  // 程序代码
}catch(异常类型2 异常的变量名2){
  // 程序代码
}catch(异常类型2 异常的变量名2){
  // 程序代码
}

上面的代码段包含了3catch块。可以在try语句后面添加任意数量的catch块。如果保护代码中发生异常,异常被抛给第一个catch块,如果抛出异常的数据类型与ExceptionType1匹配,它在这里就会被捕获。如果不匹配,它会被传递给第二个catch块,如此,直到异常被捕获或者通过所有的catch块。

try {
    file = new FileInputStream(fileName);
    x = (byte) file.read();
} catch(FileNotFoundException f) { // Not valid!
    f.printStackTrace();
    return -1;
} catch(IOException i) {
    i.printStackTrace();
    return -1;
}

异常抛出

如果一个方法没有捕获到一个检查性异常,那么该方法必须使用throws关键字来声明。throws关键字放在方法签名的尾部。也可以使用throw关键字抛出一个异常,无论它是新实例化的还是刚捕获到的。

public void test() throws Exception {
    throw new Exception();
}

从上面这一段代码可以明显的看出两者的区别。throws表示一个方法声明可能抛出一个异常,throw表示此处抛出一个已定义的异常(可以是自定义需继承Exception,也可以是java自己给出的异常类。下面方法的声明抛出一个RemoteException异常:

import java.io.*;
public class className
{
  public void deposit(double amount) throws RemoteException
  {
    // Method implementation
    throw new RemoteException();
  }
  //Remainder of class definition
}

一个方法可以声明抛出多个异常,多个异常之间用逗号隔开。例如,下面的方法声明抛出RemoteExceptionInsufficientFundsException

import java.io.*;
public class className
{
   public void withdraw(double amount) throws RemoteException,
                              InsufficientFundsException
   {
       // Method implementation
   }
   //Remainder of class definition
}

finally关键字

finally关键字用来创建在try代码块后面执行的代码块。无论是否发生异常,finally代码块中的代码总会被执行。在finally代码块中,可以运行清理类型等收尾善后性质的语句。finally代码块出现在catch代码块最后,语法如下:

try{
  // 程序代码
}catch(异常类型1 异常的变量名1){
  // 程序代码
}catch(异常类型2 异常的变量名2){
  // 程序代码
}finally{
  // 程序代码
}

其示例如下:

public class ExcepTest{
  public static void main(String args[]){
    int a[] = new int[2];
    try{
       System.out.println("Access element three :" + a[3]);
    }catch(ArrayIndexOutOfBoundsException e){
       System.out.println("Exception thrown  :" + e);
    }
    finally{
       a[0] = 6;
       System.out.println("First element value: " +a[0]);
       System.out.println("The finally statement is executed");
    }
  }
}

/**
Exception thrown  :java.lang.ArrayIndexOutOfBoundsException: 3
First element value: 6
The finally statement is executed
**/

注意,catch不能独立于try存在、在try/catch后面添加finally块并非强制性要求的、try代码后不能既没catch块也没finally块、 try, catch, finally块之间不能添加任何代码。

finallyreturn

若有finally则在catch处理后执行finally里面的代码。然而存在这样两个问题:

try{
    //待捕获代码
}catchException e{
    System.out.println("catch is begin");
    return 1
}finally{
     System.out.println("finally is begin");
}

catch里面有一个return,那么finally会不会被执行呢?答案是肯定的,上面代码的执行结果为:

catch is begin
finally is begin

也就是说会先执行catch里面的代码后执行finally里面的代码最后才return1;而如下的代码:

try{
   //待捕获代码
}catchException e{
    System.out.println("catch is begin");
    return 1
}finally{
     System.out.println("finally is begin");
     return 2 ;
}

返回的是return 2;原因很明显,就是执行了finally后已经return了,所以catch里面的return不会被执行到。也就是说finally永远都会在catchreturn前被执行。

上一页
下一页