7.2 捕捉异常

本文详细介绍了Java中的异常处理机制,包括如何使用try-catch-finally结构来捕获和处理异常,如何通过throws关键字将异常传递给调用者,以及如何利用try-with-resources语句自动关闭资源。此外,还探讨了如何捕获多个异常类型,如何重抛异常以及如何分析堆栈跟踪。

1 捕捉异常

try
{
    //这里写可能发生异常的代码
    code
    more code
    more code
}
catch (ExceptionType e)
{
    //一旦发生异常,就会跳转到这里对异常进行处理
    handler for this type
}

例如:

public void read(String filename)
{
    try
    {
        InputStream in = new FileInputStream(filename);
        int b;
        while ((b = in.read()) != -1)
        {
            process input
        }
    }
    catch (IOException exception)
    {
        exception.printStackTrace();
    }
}

当然也可以传递给方法的调用者,而不在本方法处理这个异常:

public void read(String filename) throws IOException
{
    InputStream in = new FileInputStream(filename);
    int b;
    while ((b = in.read()) != -1)
    {
        process input
    }
}

一般是这样考虑,能处理这个异常,那就不进行传递下去,如果处理不了,就传递给调用者处理。

注意:子类覆盖方法抛出的异常不能够超出父类该方法抛出的异常范围,否则,和权限修饰符一样,子类就不属于父类的定义了,而这是违背类的设计理念的。


2 捕获多个异常

try
{
    code that might throw exceptions
}
catch (FileNotFoundException e)
{
    emergency action for missing files
}
catch (UnknownHostException e)
{
    emergency action for unknown hosts
}
catch (IOException e)
{
    emergency action for all other I/O problems
}

这样也可以:

try
{
    code that might throw exceptions
}
catch (FileNotFoundException | UnknownHostException e)
{
    emergency action for missing files and unknown hosts
}
catch (IOException e)
{
    emergency action for all other I/O problems
}

3 重抛异常和异常链

try
{
    access the database
}
catch (SQLException e)
{
    //包含了更高级信息的异常
    throw new ServletException("database error: " + e.getMessage());
}
//这样重新获得那个被包装起来的异常,,通过这个方法可以把已检查异常包装成运行时异常
Throwable e = se.getCause();

4 finally语句

InputStream in = new FileInputStream(. . .);
try
{
    // 1
    code that might throw exceptions
    // 2
}
catch (IOException e)
{
    // 3
    show error message
    // 4
}
finally
{
    // 5
    in.close();
}
// 6
  1. 没有异常发生:1,2,5,6
  2. 发生异常并捕捉到异常:1,3,4,5,6
  3. 发生异常没有捕捉到:1,5

也可以没有catch块

InputStream in = . . .;
try
{
    code that might throw exceptions
}
finally
{
    in.close();
}

一般finally块用来关闭打开的资源。


5 带资源的try语句

//一般是这样写的语句
open a resource
try
{
    work with the resource
}
finally
{
    close the resource
}
//当try块结束时,会自动调用res.close()方法
try (Resource res = ...)
{
    work with res
}

例如:

try (Scanner in = new Scanner(new FileInputStream("/usr/share/dict/words")), "UTF-8")
{
    while (in.hasNext())
        System.out.println(in.next());
}

也可以打开多个资源:

try (
    Scanner in = new Scanner(new FileInputStream("/usr/share/dict/words"), "UTF-8");
    PrintWriter out = new PrintWriter("out.txt")
    )
{
    while (in.hasNext())
    out.println(in.next().toUpperCase());
}

6 分析堆栈跟踪元素

就是分析方法调用层级顺序的东西。

import java.util.*;

/**
 * A program that displays a trace feature of a recursive method call.
 * @version 1.01 2004-05-10
 * @author Cay Horstmann
 */
public class StackTraceTest
{
   /**
    * Computes the factorial of a number
    * @param n a non-negative integer
    * @return n! = 1 * 2 * . . . * n
    */
   public static int factorial(int n)
   {
      System.out.println("factorial(" + n + "):");
      Throwable t = new Throwable();
      StackTraceElement[] frames = t.getStackTrace();
      for (StackTraceElement f : frames)
         System.out.println(f);
      int r;
      if (n <= 1) r = 1;
      else r = n * factorial(n - 1);
      System.out.println("return " + r);
      return r;
   }

   public static void main(String[] args)
   {
      Scanner in = new Scanner(System.in);
      System.out.print("Enter n: ");
      int n = in.nextInt();
      factorial(n);
   }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值