Java SE 7 Exception的使用

5 篇文章 0 订阅

Java SE 7 Exception的使用

Java SE 7 中,作为Project Coin项目中众多有用的细小语言变化之一的加强型异常处理,现在来学习如何利用它。

简介:

在这边文章中,我们所涉及的一些变化是作为Java平台标准版7(Java SE 7)所发布,在JSR334(Java Specification Request)有详细的说明。现在我们重点讨论异常处理,特别是:multi-catch,rethrow,以及try-with-resources.

 

Multi-Catch Exceptions

多异常捕获已经加入到Java SE 7,他帮助我们更简便的进行异常处理,现在就把你的异常处理代码从Java SE7之前的版本迁移到Java SE7来阅读。

1

 

public class ExampleExceptionHandling
{
   public static void main( String[] args )
   {
   try {
        URL url = new URL("http://www.yoursimpledate.server/");
        BufferedReader reader = new
              BufferedReader(newInputStreamReader(url.openStream()));
        String line = reader.readLine();
        SimpleDateFormat format = new SimpleDateFormat("MM/DD/YY");
        Date date = format.parse(line);
   }
   catch(ParseException exception) {
        // handle passing in the wrong type of URL.
   }
   catch(IOException exception) {
        // handle I/O problems.
   }
   catch(ParseException exception) {
        // handle date parse problems.
   }
   }
}
 

 

在过去,如果你想要相同的逻辑代码在上面的三个异常代码块的时候,你不得不在PaseExceptionIOException中拷贝粘贴代码,一个缺乏经验或者懒惰的程序员可能认为像下面这样也是OK的。

2

 

public class ExampleExceptionHandlingLazy
{
   public static void main( String[] args )
   {
         try {
                  URL url = new URL("http://www.yoursimpledate.server/");
                  BufferedReader reader = new
             BufferedReader(new InputStreamReader(url.openStream()));
                  String line = reader.readLine();
                  SimpleDateFormat format = new SimpleDateFormat("MM/DD/YY");
                  Date date = format.parse(line);
         }
         catch(Exception exception) {
                  // I am an inexperienced or lazy programmer here.
         }
   }
}
 

 

在例2代码示例中最大的毛病就是会产生不可预料的副作用,任何代码在try代码块可能产生异常,所有异常将全部由catch子句所处理。如果一个异常既不是ParseException也不是IOException(例如:SecurityException),此异常仍然会被捕获,但是上游用户去不知道真正发生了什么?这种吞并式的异常将很难调试。

 

为了方便程序员,JavaSE7现在引入了多异常捕获,这样程序员就可以合并多个catch字句为一个单独的代码块,而不需要去使用危险的吞并似的一个异常捕获所有,或者拷贝整个代码块。

例3:

 

public class ExampleExceptionHandlingNew
{
   public static void main( String[] args )
   {
         try {
                  URL url = new URL("http://www.yoursimpledate.server/");
                  BufferedReader reader = new BufferedReader(
                           new InputStreamReader(url.openStream()));
                  String line = reader.readLine();
                  SimpleDateFormat format = new SimpleDateFormat("MM/DD/YY");
                  Date date = format.parse(line);
         }
         catch(ParseException | IOException exception) {
                  // handle our problems here.
         }
   }
}
 

 

示例3就展示了怎么合理的合并两个catch块语句,注意catch子句的语法(ParseException|IOException),catch子句可以捕获ParseExceptionIOException。所以如果想多个不同的异常共用相同的异常处理代码,那么就可以使用这种管道语法(ExceptionType…|ExceptionType variable)

 

Rethrowing Exceptions

当你在处理异常的时候,有时候想把一个处理完后的异常往外抛的时候,没有经验的程序员可能认为用下面这种方式操作是合理的

4

 

public class ExampleExceptionRethrowInvalid
{
   public static void demoRethrow()throws IOException {
         try {
                  // forcing an IOException here as an example,
                 // normally some code could trigger this.
                 throw new IOException(“Error”);
         }
         catch(Exception exception) {
                  /*
                   * Do some handling and then rethrow.
                   */
                  throw exception;
         }
   }
   
   public static void main( String[] args )
   {
         try {
                  demoRethrow();
                  }
         catch(IOException exception) {
         System.err.println(exception.getMessage());
         }
   }
}
 

很遗憾的是编译器没发完成编译工作,下面这段代码展示了如何去处理完异常后再往外抛。

5

 

public class ExampleExceptionRethrowOld
{
   public static demoRethrow() {
         try {
                  throw new IOException("Error");
         }
         catch(IOException exception) {
                  /*
                   * Do some handling and then rethrow.
                   */
                  throw new RuntimeException(exception);
         }
   }
   
   public static void main( String[] args )
   {
         try {
                  demoRethrow();
         }
         catch(RuntimeException exception) {
         System.err.println(exception.getCause().getMessage());
         }
   }
}
 

上面这个例子的毛病就在于不能抛出原生的异常,他用另外一个异常包裹了,这就意味着代码的下游需要注意他是被包装了的。所以为了捕获到这个确切的原生异常,在Java SE7中做出变化是必须的,如下代码:

6

 

public class ExampleExceptionRethrowSE7
{
   public static demoRethrow() throws IOException {
         try {
                  throw new IOException("Error");
         }
         catch(Exception exception) {
                  /*
                   * Do some handling and then rethrow.
                   */
                  throw exception;
         }
   }
   
   public static void main( String[] args )
   {
         try {
                  demoRethrow();
         }
         catch(IOException exception) {
         System.err.println(exception.getMessage());
         }
   }
}
 

上面的示例在JavaSE7中能正确的编译(译者注)

 

Try-with-Resources

你可能注意到了在第一个例子中有这样一个问题(这就是为什么当你不知道示例代码做了些什么的时候,你永远也不要在生产环境中使用)。这个问题就是没有对资源的清空。例7是一个修改的版本,描述了怎样在JavaSE7之前的版本中校正这个问题。

7

 

public class ExampleTryResources
{
   public static void main(String[] args)
   {
         BufferedReader reader = null;
   
         try {
                  URL url = new URL("http://www.yoursimpledate.server/");
                  reader = new BufferedReader(new 
                                   InputStreamReader(url.openStream()));
                  String line = reader.readLine();
                  SimpleDateFormat format = new SimpleDateFormat("MM/DD/YY");
                  Date date = format.parse(line);
         }
         catch (MalformedURLException exception) {
                  // handle passing in the wrong type of URL.
         } catch (IOException exception) {
                  // handle I/O problems.
         } catch (ParseException exception) {
                  // handle date parse problems.
         } finally {
                  if (reader != null) {
                           try {
                                   reader.close();
                                    } catch (IOException ex) {
                                   ex.printStackTrace();
                           }
                  }
         }
   }
}
 

我们注意到代码中添加了一个final代码块,如果BufferedReader被赋值了,它将被关闭,而且变量reader也已经移到了try代码块的外面了。当一个I/O异常发生的时候关闭字符流就要多些很多的代码。

 

JavaSE7中,可以更简洁更清爽,如例8所示,这种新的语法允许你把资源作为try代码块的一部分,这意味着可以提前定义好资源然后执行完try代码块的时候虚拟机将自动关闭资源。

8

 

public static void main(String[] args)
{
   try (BufferedReader reader = new BufferedReader(
         new InputStreamReader(
         new URL("http://www.yoursimpledate.server/").openStream())))
   {
         String line = reader.readLine();
         SimpleDateFormat format = new SimpleDateFormat("MM/DD/YY");
         Date date = format.parse(line);
   } catch (ParseException | IOException exception) {
         // handle I/O problems.
   }
}
 

在例8中实际发生变化的是在try(….)语句,需要注意的是这个特性只有在资源实例实现了AutoCloseable接口的实例才能生效

 

总结:

异常处理在javaSE7中,你不仅可以写出更简洁的程序,正如multi-catch示例所演示的一样,而且在可以处理完部分异常后再往外抛出去。如re_throw 例子所示,JavaSE7同样有助于减少易于出错的异常清理。正如我们在try-with resource例子中看到的一样。这些特征和其他Project Coin项目中提供的一样,能使Java程序员写代码更有效率以及写出更高效的代码。

 

附上自己的一点感受:第一次这样认真的去翻译一遍文章,以往看完一遍文章可以不到二十分钟,但是翻译工作花了我两个小时,非常认真的在做,发现翻译不仅可以学外语,还可以学语文。对自己的语言组织也有提高,终于体会到翻译书籍的人特别不容易。2012/3/1  1:20

 

原文连接http://www.oracle.com/technetwork/articles/java/java7exceptions-486908.html

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值