zoukankan      html  css  js  c++  java
  • [转] Java se 7新特性研究(二)

    详见: http://blog.yemou.net/article/query/info/tytfjhfascvhzxcytp82

     

    今天主要研究Java se 7中异常处理的新功能.从今天开始正在将jdk7的说法改为java se 7跟oracle官网的一致

    一、新增了try-with-resource 异常声明

    在JDK7中只要实现了AutoCloseable或Closeable接口的类或接口,都可以使用try-with-resource来实现异常处理和资源关闭。下面做一下

    JDK7以前:

    static String readFirstLingFromFile(String path) throws IOException{

      BufferedReader br=null;

      try{

      br=new BufferedReader(new FileReader(path));

      return br.readLine();

      }catch(IOException e){
       e.printStackTrace();

      }finally{
       if(br!=null)
         br.close();
      }

      return null;

      }

    JDK7 及以后版本:

    static String readFirstLineFromFile(String path) throws IOException {
      try (BufferedReader br = new BufferedReader(new FileReader(path))) {
        return br.readLine();
      }
    }

    通过以上对比我们可以发现具有以下优点:

    1、代码更精练。在Java se 7以前版都有finally块,如果使用一些框架可能会将finally块交由框架处理,如spring。在jdk7及后的版本,只要资源类实现了AutoCloseable或Closeable程序在执行宛try块后会自动close所使用的资源无论br.readLine()是否抛出异常。我估计针对jdk7像spring这些框架也会做出一些比较大的调整。

     

    2、代码更完全。在出现资源泻漏的程序中,很多情况是开发人员没有或没有正确地关闭资源导致的。JDK7后采用try-with-resource的方式,则可以将资源关闭这种与业务实现没有很大直接关系的工作交给JVM完成。省去了部分开发中可能出现的代码风险。

     

     异常抛出顺序。在Java se 7中的try-with-resource机制中异常的抛出顺序与Java se 7以前的版本有一点不一样。

    JDK7以前如果rd.readLine()与rd.close()(在finally块中)都抛出异常则只会抛出finally块中的异常,不会抛出rd.readLine();中的异常。这样经常会导致得到的异常信息不是调用程序想要得到的。

    JDK7及以后版本中如果采用try-with-resource机制,如果在try-with-resource声明中抛出异(可能是文件无法打或都文件无法关闭)同时rd.readLine();也势出异常,则只会势出rd.readLine()的异常。

     

    try-with-resource可以声明多个资源。下面的例子是在一个zip文件中检索文件名并将检索后的文件名存入一个txt文件中:

     

    public static void writeToFileZipFileContents(String zipFileName, String outputFileName)
        throws java.io.IOException {

        java.nio.charset.Charset charset = java.nio.charset.Charset.forName("US-ASCII");
        java.nio.file.Path outputFilePath = java.nio.file.Paths.get(outputFileName);

        // Open zip file and create output file with try-with-resources statement

        try (
          java.util.zip.ZipFile zf = new java.util.zip.ZipFile(zipFileName);
          java.io.BufferedWriter writer = java.nio.file.Files.newBufferedWriter(outputFilePath, charset)
        ) {

          // Enumerate each entry

          for (java.util.Enumeration entries = zf.entries(); entries.hasMoreElements();) {

            // Get the entry name and write it to the output file

            String newLine = System.getProperty("line.separator");
            String zipEntryName = ((java.util.zip.ZipEntry)entries.nextElement()).getName() + newLine;
            writer.write(zipEntryName, 0, zipEntryName.length());
          }
        }
      }

    上面的例子,无论正常执行还是有异常抛出,zf和writer都会被执行close()方法。不过需要注意的是在JVM里调用的顺序是与声明的顺序相反。在JVM里调用的顺序为:

    writer.close();

    zf.close();

    所在在使用时一定要注意。

    声明资源时要分析好资源关闭顺序。

    JDK7及后的版本的JDBC也支持try-with-resource.如下示例:

     public static void viewTable(Connection con) throws SQLException {

        String query = "select COF_NAME, SUP_ID, PRICE, SALES, TOTAL from COFFEES";

        try (Statement stmt = con.createStatement()) {

          ResultSet rs = stmt.executeQuery(query);

          while (rs.next()) {
            String coffeeName = rs.getString("COF_NAME");
            int supplierID = rs.getInt("SUP_ID");
            float price = rs.getFloat("PRICE");
            int sales = rs.getInt("SALES");
            int total = rs.getInt("TOTAL");
            System.out.println(coffeeName + ", " + supplierID + ", " + price +
                               ", " + sales + ", " + total);
          }

        } catch (SQLException e) {
          JDBCTutorialUtilities.printSQLException(e);
        }
      }

    在try-with-resource中也可以有catch与finally块。只是catch与finally块是在处理完try-with-resource后才会执行。

    二、catch多种异常并抛出新的异常

    1、catch多种异常抛出一种异常

    在JDK7以前大家会经常处理类似下面的代码:

    try{

    .........

    }catch (IOException ex) {
         logger.log(ex);
         throw new SpecialException();
    catch (SQLException ex) {
         logger.log(ex);
         throw new SpecialException();
    }

    这处理导致代码非常的难看,和许多重复的代码。JDK7后,大家可以这样处理:

    try{

    .........

    }catch (IOException | SQLException ex) {
         logger.log(ex);
         throw new SpecialException();
    }

    注:在上面例子中的ex是隐式的final不可以在catch块中改变ex.

    2、Rethrowing Exceptions with More Inclusive Type Checking

    在Java se 7以前的版本。在方法声明中声明抛出的异常如果在方法体内没有抛出是不允许的。如下示例:

    static class FirstException extends Exception { }
      static class SecondException extends Exception { }

      public void rethrowException(String exceptionName) throws Exception {
        try {
          if (exceptionName.equals("First")) {
            throw new FirstException();
          } else {
            throw new SecondException();
          }
        } catch (Exception e) {
          throw e;
        }
      }

    上面这种代码其实很多开发人员都不喜欢,有的可能会提出一些改进方法,但无法做到非常精准的方法异常声明。下面看一下Java se 7的做法:

     public void rethrowException(String exceptionName)
      throws Exception, FirstException, SecondException {
        try {
          // ...
        }
        catch (Exception e) {
          throw e;
        }
      }

    异常处理这一块,Java se7改进了许多,开发人员需要认真的学习和试验。

    今天先谈到这里。接下来将谈一下下划线在数字表示中的应用和泛型的改进。

  • 相关阅读:
    Java 正则表达式
    连续子数组最大和
    背包问题
    二叉树的数组存储
    各种鸟
    mac关闭和开启启动声
    关于栈和队列随想
    linux主机名 hostname
    mysql创建新用户并且授权远程访问
    关于linux的用户
  • 原文地址:https://www.cnblogs.com/grefr/p/5046287.html
Copyright © 2011-2022 走看看