• 博客园logo
  • 会员
  • 周边
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • YouClaw
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
风吹花落泪如雨
博客园    首页    新随笔    联系   管理    订阅  订阅

JAVA高级特性(一)异常处理

Java中的异常类型

Java从Throwable直接派生出Exception和Error。其中Exception是可以抛出的基本类型,在Java类库、方法以及运行时故障中都可能抛出Exception型异常;Error表示编译时和系统错误。异常类的结构层次图如下:

 

所有的RuntimeException类及其子类的实例被称为Runtime异常;

不是RuntimeException及其子类的异常实例则被称为Checked异常。

Java如何处理异常

java7新增的多异常捕获: 

try{
}catch (NumberFormatException | ArithmeticException ie){
   //捕获多异常时,异常变量默认有final修饰,下面代码出错
   ie = new ArithmeticException("test");
}catch (Exception e){
   //捕获一种类型的异常时,异常变量没有final修饰,下面代码正确
   e = new RuntimeException("test");
}

 访问异常信息:

getMessage():返回该异常的详细描述字符串
printStackTrance():将该异常的跟踪栈信息输出到标准错误输出
printStackTrance(PrintStream s):将该异常的跟踪栈信息输出到指定输出流
getStackTrace():返回该异常的跟踪栈信息

使用finally回收资源:

当Java程序执行try、catch块时遇到了return或throw语句,这两个语句会导致该方法立即结束,但是系统会先去寻找该异常处理流程是否包含finally方法。若有,执行finally方法。

若finally有return语句,则导致try、catch语句的return失效。

注意:除非调用了退出虚拟机的方法(System.exit(0)),否则不管在try块、catch块中执行怎样的代码,异常处理的finally块总会被执行。

Java9增强的自动关闭资源的try语句:

Closeable是AutoCloseable的子接口,可以被自动关闭的资源类要么实现AtuoCloseable接口,要么实现Closeable接口,Closeable接口里的close()方法声明抛出了IOException,因此它的实现类在实现close()方法时只能声明抛出IOException或其子类;AutoCloseable接口里的close()方法声明抛出了Exception,因此它的实现类在实现close()方法时可以声明抛出任何异常。

public class AutoCloseTest{
   public static void main(String[] args)throws IOException{
    //有final修饰的资源
    final BufferedReader br = new BufferedReader(
              new FileReader("AutoCloseTest.java"));
     //没有使用final,但只要不对该变量重新赋值,该变量就是有效的final
    PrintStream ps = new PrintStream(
          new FileOutputStream("a.txt"));
    //只要将两个资源放在try后的圆括号内即可
     try(br;ps){
          //使用两个资源
          System.out.println(br.readLine());
          ps.println("庄生晓梦迷蝴蝶");
    }    
   }
}

使用throws声明抛出异常:

public class ThrowsTest{
   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");
   }
}

使用throw声明抛出异常:

在大部分时候推荐使用Runtime异常,而不使用Checked异常

throw语句抛出的不是异常类,而是一个异常实例,而且每次只能抛出一个异常实例:

public class ThrowTest{
   public static void main(String[] args){
      try{
       //调用声明抛出的Checked异常的方法,要么显示捕获该异常
     //要么在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("异常");
      } 
   }
   public static void throwRuntime(int a){
      if(a>0){
         //自行抛出RuntimeException异常,既可以显示捕获该异常
     //也可不理会,把该异常交给该方法调用者处理
       throw new RuntimeException("异常");
      } 
   }
}

自定义异常:

定义异常类时通常需要提供两个构造器:
①一个是无参的构造器;
②另一个是带一个字符串参数的构造器。(也就是异常对象的getMessage()方法的返回值)

public class AuctionException extends Exception{
   //无参的构造器
   public AuctionException(){}
   //带一个字符串参数的构造器
   public AuctionException (String msg){
     super(msg);
   }
}

catch和throw同时使用:

当一个异常出现时没,单靠某个方法无法完全处理该异常,必须由几个方法协作才可完全处理该异常。

在异常出现的当前方法中,程序只对异常进行部分处理,还有些处理需要在该方法的调用者中才能完成,所以应该再次抛出异常,让该方法的调用者也能捕获到异常。

public class AuctionTest{
   //因为该方法中显示抛出了AuctionException异常
   //所以此处需要声明抛出AuctionException异常
   public void bid(String bidPrice)throws AuctionException{
      try{

      }catch(Exception e){
        //此处完成本方法中科院对异常执行的修复处理
          //此处仅仅是在控制台打印异常的跟踪栈信息
          e.printStackTrace();
          //再次抛出自定义异常
         throw new AuctionException("出错"); 
       }
   }
   public static void main(String[] args){
      AuctionTest at = new AuctionTest();
      try{
     at.bid("df");
      }catch(AuctionException ae){
         //再次捕获到bid()方法中的异常,并对异常进行处理
         System.err.println(ae.getMessage());
       }
   }
}

 

 

posted @ 2018-06-10 00:18  风吹花落泪如雨  阅读(121)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2026
浙公网安备 33010602011771号 浙ICP备2021040463号-3