疯狂JAVA讲义---第十章:异常处理

来源:互联网 发布:windows 图标改小 编辑:程序博客网 时间:2024/04/29 08:05

Java的异常处理主要通过try,catch,finally,throw,throws五个关键字。

Java把异常当作对象来处理,并定义一个基类java.lang.Throwable作为所有异常的超类。在Java API中已经定义了许多异常类,这些异常类分为两大类,错误Error和异常Exception,Java异常体系结构呈树状,如下

 

 

下面举个异常类常见使用,eg

  1. public class TestDiv
  2. {
  3.     public static void main(String[] args) 
  4.     {
  5.         try
  6.         {
  7.             int a = Integer.parseInt(args[0]);
  8.             int b = Integer.parseInt(args[1]);
  9.             int c = a / b;
  10.             System.out.println("您输入的两个数相除的结果是:" + a / b);
  11.         }
  12.         catch (IndexOutOfBoundsException ie)
  13.         {
  14.             System.out.println("数组越界:运行程序时输入的参数个数不够");
  15.         }
  16.         catch (NumberFormatException ne)
  17.         {
  18.             System.out.println("数字格式异常:程序只能接受整数参数");
  19.         }
  20.         catch (ArithmeticException ae)
  21.         {
  22.             System.out.println("算术异常");
  23.         }
  24.         catch (Exception e)
  25.         {
  26.             e.printStackTrace();
  27.             System.out.println("未知异常");
  28.         }
  29.     }
  30. }

这里要注意:一定要先捕获小的异常

finally主要用在回收写物理资源(网络连接,数据库连接,文件连接等),eg

  1. public class TestFinally
  2. {
  3.     public static void main(String[] args) 
  4.     {
  5.         FileInputStream fis = null;
  6.         try
  7.         {
  8.             fis = new FileInputStream("a.txt"); 
  9.         }
  10.         catch (IOException ioe)
  11.         {
  12.             System.out.println(ioe.getMessage());
  13.             //return语句强制方法返回
  14.             //return ;
  15.             //使用exit来退出虚拟机
  16.             System.exit(1);
  17.         }
  18.         finally
  19.         {
  20.             //关闭磁盘文件,回收资源
  21.             if (fis != null)
  22.             {
  23.                 try
  24.                 {
  25.                     fis.close();
  26.                 }
  27.                 catch (IOException ioe)
  28.                 {
  29.                     ioe.printStackTrace();
  30.                 }
  31.             }
  32.             System.out.println("程序已经执行了finally里的资源回收!");
  33.         }
  34.     }
  35. }

这里要注意:finally中不要使用return或throw,因为这会使try,catch中的return或throw失效

java独特的提供了checked异常这使一些问题能在编译时就解决。

下面再举throw和throws的例子,eg

  1. public class TestThrow
  2. {
  3.     public static void main(String[] args) 
  4.     {
  5.         try
  6.         {
  7.             //调用带throws声明的方法,必须显式捕获该异常
  8.             //否则,必须在main方法中再次声明抛出
  9.             throwChecked(-3);           
  10.         }
  11.         catch (Exception e)
  12.         {
  13.             System.out.println(e.getMessage());
  14.         }
  15.         //调用抛出Runtime异常的方法既可以显式捕获该异常,
  16.         //也可不理会该异常
  17.         throwRuntime(3);
  18.     }
  19.     public static void throwChecked(int a)throws Exception
  20.     {
  21.         if (a > 0)
  22.         {
  23.             //自行抛出Exception异常
  24.             //该代码必须处于try块里,或处于带throws声明的方法中
  25.             throw new Exception("a的值大于0,不符合要求");
  26.         }
  27.     }
  28.     public static void throwRuntime(int a)
  29.     {
  30.         if (a > 0)
  31.         {
  32.             //自行抛出RuntimeException异常,既可以显式捕获该异常
  33.             //也可完全不理会该异常,把该异常交给该方法调用者处理
  34.             throw new RuntimeException("a的值大于0,不符合要求");
  35.         }
  36.     }
  37. }

然后我简单讲下,自定义异常类,其实只要继承另外的异常类,实现2个构造方法,eg

  1. public class AuctionException extends Exception
  2. {
  3.     //异常类无参数的构造器
  4.     public AuctionException(){}
  5.     //带一个字符串参数的构造器
  6.     public AuctionException(String msg)
  7.     {
  8.         super(msg);
  9.     }
  10. }

利用catch和throw同时使用形成异常链,eg

  1. public class TestAuction
  2. {
  3.     private double initPrice = 30.0;
  4.     public void bid(String bidPrice)
  5.         throws AuctionException
  6.     {
  7.         double d = 0.0;
  8.         try
  9.         {
  10.             d = Double.parseDouble(bidPrice);
  11.         }
  12.         catch (Exception e)
  13.         {
  14.             //此处完成本方法中可以对异常执行的修复处理,此处仅仅是在控制台打印异常跟踪信息。
  15.             e.printStackTrace();
  16.             //再次抛出自定义异常
  17.             throw new AuctionException("竞拍价必须是数值,不能包含其他字符!");
  18.         }
  19.         if (initPrice > d)
  20.         {
  21.             throw new AuctionException("竞拍价比起拍价低,不允许竞拍!");
  22.         }
  23.         initPrice = d;
  24.     }
  25.     public static void main(String[] args) 
  26.     {
  27.         TestAuction ta = new TestAuction();
  28.         try
  29.         {
  30.             ta.bid("df");
  31.         }
  32.         catch (AuctionException ae)
  33.         {
  34.             //main方法再次捕捉到bid方法中的异常。并对该异常进行处理
  35.             System.err.println(ae.getMessage());
  36.         }
  37.     }
  38. }

这样异常越来越精确,便于调试,纠错。

异常跟踪栈(printStackTrace这方法就是打出的)这是为了方便你找到异常的源头。使用IDE的人调试时都离不开它。

下面举两个典型例子,大家随便加点断点,单步走走,看看堆栈,一定收获颇丰,eg

  1. class SelfException extends Exception
  2. {
  3.     SelfException(){}
  4.     SelfException(String msg)
  5.     {
  6.         super(msg);
  7.     }
  8. }
  9. public class TestPrintStackTrace
  10. {
  11.     public static void main(String[] args)throws SelfException
  12.     {
  13.         firstMethod();
  14.     }
  15.     public static void firstMethod()throws SelfException
  16.     {
  17.         secondMethod();
  18.     }
  19.     public static void secondMethod()throws SelfException
  20.     {
  21.         thirdMethod();
  22.     }
  23.     public static void thirdMethod()throws SelfException
  24.     {
  25.         throw new SelfException("自定义异常信息");
  26.     }
  27. }

下面这个例子加强你的多线程的调试能力

  1. public class TestThreadException implements Runnable
  2. {
  3.     public void run()
  4.     {
  5.         firstMethod();
  6.     }
  7.     public void firstMethod()
  8.     {
  9.         secondMethod();
  10.     }
  11.     public void secondMethod()
  12.     {
  13.         int a = 5;
  14.         int b = 0;
  15.         int c = a / b;
  16.     }
  17.     public static void main(String[] args) 
  18.     {
  19.         new Thread(new TestThreadException()).start();
  20.     }
  21. }

最后警告句:

能自己处理的异常就自己处理掉,抛出异常系统开销很大,try..catch的范围越小越好,大家不要偷懒,不然不容易发现问题。

能自己处理的异常就自己处理掉,抛出异常系统开销很大,try..catch的范围越小越好,大家不要偷懒,不然不容易发现问题。

能自己处理的异常就自己处理掉,抛出异常系统开销很大,try..catch的范围越小越好,大家不要偷懒,不然不容易发现问题。