Checked异常和Runtime异常体系

使用throws声明抛出异常

 

一旦使用throws语句声明抛出该异常,程序就无须使用try...catch块来捕获该异常

 

public class ThrowsTest

{

           public static void main(String[] args)throws IOException

           {

                    FileInputStream fis = new FileInputStream("a.txt");

            }

}

 

编译结果:

 

 

 

 

import java.io.*;

public  class TestThrows2

{

          public static void main(String[] args) throws Exception

          {

                     //因为test()方法声明抛出IOException异常

                    //所以调用该方法的代码要么处于try...catch块中

                     //要么处于另一个带throws声明抛出的方法中

                     test();

                  

           }

    

           public static void test() throws IOException

            {

                         //因为FileInputStream的构造器声明抛出IOException异常

                         //所以调用FileInputStream的代码要么处于try...catch块中

                         //要么处于另一个带throws声明抛出的方法中

                         FileInputStream fis = new FileInputStream("a.txt");

            }

}

 

 

 

public class OverrideThrows

{

             public void test() throws IOException

             {

                      FileInputStream fis = new FileInputStream("a.txt");

              }

 

}

 

class Sub extends OverrideThrows

{

               //下面代码无法通过编译:子类方法声明抛出了比父类方法更大的异常

               public void test() throws Exception

               {

                      //.....

               }

}

 

 

 

Checked异常有优势:Checked异常能在编译时提醒程序员代码可能存在的问题,提醒程序员必须注意处理该异常,或者声明该异常由该方法调用者来处理,从而可以避免程序员因为粗心而忘记处理该异常错误。

 

 

》》使用throw抛出异常

 

 

如果需要在程序中自行抛出异常,应使用throw语句,throw语句可以单独使用,throw语句抛出的不是异常类,而是一个异常实例,而且每次只能抛出一个异常实例:

 

throw ExceptionInstance

 

 

看代码:

 

public class TestThrow

{

          public static void main(String[] args)

          {

                     try

                     {

                                   //调用带throws声明的方法,必须显式捕获该异常

                                   //否则,必须在main方法中再次声明抛出

                                   throwChecked(-3);

                      }

                      catch(Exception e)

                      {

                                System.out.println(e.getMessage());

                       }

                       //调用抛出Runtime异常的方法既可以显式捕获该异常

                       //也可不理会异常

                       throwRuntime(3);

           }

 

           public static void throwChecked(int a ) throws Exception

            {

                           if(a >0 )

                            {

                                        //自行抛出Exception 异常

                                        //该代码必须处于try块里,或处于带throws声明的方法中

                                         throw new Exception("a的值大于0,不符合要求");

                             }

 

                           public static void throwRuntime(int a )

                           {

                                       if(a>0)

                                       {

                                                   //自行抛出RuntimeException异常,既可以显式捕获该异常

                                                   //也可完全不理会该异常,把该异常交给该方法调用者处理

                                                   throw new RuntimeException("a的值大于0,不符合要求");

                                        }

                            }

             }

 

 

}

 

编译结果:

 

 

》》自定义异常类

 

 

public class AuctionException extends Exception

{

               //异常类无参数的构造器

               public AuctionException()

               {}

               //带一个字符串参数的构造器

               public AuctionException(String msg)

               {

                           super(msg);

               }

 }

 

 

》》catch和throw同时使用

 

 

public class TestAuction

{

          private double initPrice = 30.0;

 

          //因为该方法中显式地throw了AuctionException异常

          //所以此处需要声明抛出AuctionException异常

          public void bid(String bidPrice) throws AuctionException

           {

                       double d = 0.0;

                       try

                        {

                                  d = Double.parseDouble(bidprice);

                         }

                         catch(Exception e)

                         {

                                    //此处完成本方法中可以对异常执行的修复处理,此处仅仅是在控制台打印异常跟踪栈信息

                                     e.printStackTrace();

                                    //再次抛出自定义异常

                                     throw new AuctionException("竟拍价必须是数值,不能包含其他字符");

                           }

                            if(intPrice>d)

                            {

                                         throw new AuctionException("竟拍价比起拍价低,不允许竟拍");

                              }

                              initPrice = d;

             }

 

             public static void main(String[] args)

              {

                         TestAuction ta = new TestAuction();

                         try

                         {

                                       ta.bid("df");

                           }

                           catch(AuctionException ae)

                           {

                                     //main方法再次捕捉到bid方法中的异常,并对该异常进行处理

                                     System.err.println(ae.getMessage());

                            }

               }

                                                        

}

 

 

编译结果:

 

 

 

》》JAVA异常链

 

 

程序先捕获原始的异常,然后抛出一个新的业务异常,新的业务异常中包含了对用户的提示信息,这种处理方式被称为异常转译

 

 

public calSal throws SalException

{

           try

            {

                        //实现结算工资的业务逻辑

                        ...

             }

            catch(SQLException sqle)

            {

                           //把原始异常中的message就是向用户提示

                            throw new SalException("访问底层数据库出现异常");

 

               }

             catch(Exception e)

              {

                        //把原始异常记录下来,留给管理员

                        ...

                        //下面异常中的message就是向用户的提示

                        throw new SalException("系统出现未知异常");

               }

}

 

 

 

》》JAVA的异常跟踪栈

 

class SelfException extends Exception

{

         SelfException()

          {}

         SelfException(String msg)

         {

                   super(msg);

          }

}

 

public class PrintStackTraceTest

{

             public static void main(String[] args)throws SelfException

             {

                        firstMethod();

              }

 

             public static void firstMethod() throws SelfException

             {

                        secondMethod();

             }

 

             public static void secondMethod() throws selfException

             {

                         thirdMethod();

             }

 

            public static void thirdMethod()throws SelfException

             {

                      throw new SelfException("自定义异常信息");

 

 

             }

}

 

编译结果:

 

 

 

 

 

下面代码是多线程中发生异常的情形:

 

public class TestThreadException implements Runnable

{

            public void run()

            {

                     firstMethod();

             }

 

            public void firstMethod()

            {

                      secondMethod():

             }

 

            public void secondMethod()

             {

                       int a = 5;

                        int b = 0;

                        int c = a/b;

              }

 

             public static void main(String[] args)

             {

                       new Thread(new TestThreadException()).start();

             }

}

 

》异常处理规则

》不要过度使用异常

》不要使用过于庞大的try块 

》避免使用CatchAll语句

》不要忽略捕获到的异常

posted on 2013-11-06 00:17  heartstage  阅读(500)  评论(0编辑  收藏  举报

导航