`

[转] 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虚拟机规范(Java SE 7)-完整目录书签文字版

    Java SE 7(Java Standard Edition 7)是Java发展的一个重要版本,引入了许多新特性和改进,使得开发者能够编写更高效、更可靠的代码。在《Java虚拟机规范(Java SE 7)》中,详细阐述了JVM的工作原理、内存模型、类...

    Java虚拟机规范(Java_SE_7).pdf中文版

    Java SE 7版的虚拟机规范是对之前版本的更新,它详述了虚拟机的最新标准,以及如何保证不同的Java虚拟机实现(例如Oracle HotSpot、OpenJDK、IBM J9等)能够提供统一的外部接口和行为。 从1999年《Java虚拟机规范...

    Java虚拟机规范(SE 7中文版)

    《Java虚拟机规范(JavaSE7版)》是程序员深入了解Java语言运行机制不可或缺的文档。它不是特定虚拟机实现的说明书,而是一份确保不同公司实现的Java虚拟机具有一致外部接口的契约文档。这份文档是Java程序员的基础...

    JAVA SE6.0编程指南源码

    通过深入研究"编程指南代码",开发者可以了解到这些特性的实际应用和最佳实践,同时也可以学习到如何利用Java SE 6.0的工具和API解决问题。这样的源码分析对于初学者来说是宝贵的教育资源,对于有经验的开发者则是...

    Java虚拟机规范(Java SE 7)

    Java SE 7版的规范进一步完善了对新特性的支持,例如增强的泛型支持、改进的枚举类型处理等。 #### 五、译者贡献 本书由多位译者合作完成,他们在Java技术领域有着丰富的经验和深厚的专业背景。例如: - **周志明...

    Java虚拟机规范(Java_SE_7).pdf

    ### Java虚拟机规范(Java SE 7)关键知识点解析 #### 一、概述 《Java虚拟机规范(Java SE 7版)》是一份详细介绍了Java虚拟机(JVM)架构和运行机制的重要文档。这份规范不仅是Java开发人员深入了解Java语言特性的...

    Java虚拟机规范 Java SE 7 中文版

    ### Java虚拟机规范 Java SE 7 版 详解 #### 一、概述 《Java虚拟机规范(Java SE 7版)》是一本详细介绍Java虚拟机(JVM)工作原理的标准文档,由Tim Lindholm、Frank Yellin、Gilad Bracha、Alex Buckley撰写。该...

    Java虚拟机规范(中文版) Java SE 7

    ### Java虚拟机规范(中文版)Java SE 7 #### 概述 《Java虚拟机规范(Java SE 7版)》是Java虚拟机领域的权威文档之一,它为Java虚拟机的设计提供了一个标准,确保了不同公司开发的Java虚拟机能够保持一致的行为...

    Java SE 源码 Java SE 源码

    Java SE(标准版)是Java开发平台的核心,它包含了运行Java应用程序所需的所有工具和库。源码对于理解Java的工作原理、学习编程技巧以及进行高级调试和优化至关重要。在这个压缩包中,你可能找到了Java SE的原始源...

    Java虚拟机规范 SE7

    《Java虚拟机规范(JavaSE7版)》不仅是Java开发者深入学习和研究的宝典,也是JVM领域内理论与实践结合的典范。通过对这份规范的学习,开发者能够更加熟练地掌握Java编程技巧,提高代码质量和系统性能。同时,它也为...

Global site tag (gtag.js) - Google Analytics