`

[转]Java 7新特性:自动资源管理(ARM)和AutoClosable接口教程

    博客分类:
  • java
阅读更多

转自:http://www.4byte.cn/learning/84919/java-7-xin-te-xing-zi-dong-zi-yuan-guan-li-arm-he-autoclosable-jie-kou-jiao-cheng.html

 

Java 7的 try-with-resource语法的目的是提高Java开发人员的效率,使得他们不需要在编写代码时考虑资源释放问题。大多数的这类"清理"问题是由于异常发生时清理方法没有被调用产生,因此,这篇文章重点看看当异常抛出时 try-with-resource 代码是如何工作的。

来点异常先

我将在上一篇教程的例子中加上下面三个异常:

class OpenException  extends Exception{}class SwingException extends Exception{}class CloseException extends Exception{}

为了保持简单性,这篇教程中我们仅关注OpenDoor类。

OpenDoor类

这个版本的OpenDoor类的每个方法都会抛出异常。构造函数会抛出OpenException, swing()方法会抛出SwingExceptionclose方法会抛出CloseException。我说的只是可能下面的代码中,所有的抛出异常部分都被注释了:

class OpenDoor implements AutoCloseable {

  public OpenDoor() throws Exception { 
    System.out.println("The door is open."); 
    //throw new OpenException()
  };

  public void swing() throws Exception {
    System.out.println("The door is becoming unhinged.");
    //throw new SwingException(); 
  }

  public void close() throws Exception {

    System.out.println("The door is closed.");
    // throw new CloseException();
  }}

可执行的TryWithResources

下面定义TryWithResources类,请注意catch块中得e.getClass()方法。

public class TryWithResources {

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

    try ( OpenDoor door = new OpenDoor() ) {
      door.swing();
    }
    catch (Exception e) {
      System.out.println("Is there a draft? " + e.getClass());
    }
    finally {
      System.out.println("I'm putting a sweater on, regardless. ");
    }
  }}

运行上面的代码,如果没有抛出异常的话,输出应该是这样的:

The door is open.The door is becoming unhinged.The door is closed.
I'm putting a sweater on, regardless.

当door的构造方法被调用后门被打开,当门被晃动后,门被自动关闭了(try-with-resource代码的魔法),最后finally的代码被调用。

别忘了,我们还有三个异常目前被注释掉了,让我们一个个的抛出他们。

在'try-with-resource'初始化代码块的异常(构造函数抛出)

如果OpenDoor的构造函数抛出异常时会发生什么?close()方法是否还会被自动调用?让我们来试一下就知道了,去掉构造函数中异常代码的注释:

public OpenDoor() throws Exception {
    System.out.println("The door is open.");
    throw new OpenException();}

代码海星的结果如下:

The door is open.Is there a draft? class OpenException
I'm putting a sweater on, regardless.

可以看到,当构造函数抛出异常时try-with-resource代码体部分的代码没有被执行。当声明资源时,如果有异常抛出,可以认为资源并未正确初始化,所以并需要释放资源。然而,需要注意的时,如果其他资源已被正确初始化,那么还是会按照声明相反的顺序调用那些资源的close()方法。

try-with-resource代码块中抛出的异常

如果在swing方法中抛出异常,会发生什么呢?

public void swing() throws Exception {
    System.out.println("The door is becoming unhinged.");
    throw new SwingException(); 
}

上面代码的输出如下:

The door is open.The door is becoming unhinged.The door is closed.Is there a draft? class SwingException
I'm putting a sweater on, regardless.

从上面的输出我们可以了解到:

  1. OpenDoor的构造方法被调用了,第一行输出

  2. OpenDoorswing方法也被调用了,第二行输出

  3. 抛出了SwingException

  4. close方法被调用,第四行输出

  5. 异常被catch块捕获,第五行输出

  6. 执行finally代码块,地六行输出。

只是try-with-resources代码块的标准行为,尽管会使人很困惑:什么时候会执行close方法?规则是:任何AutoCloseable对象的close方法会在任何catch块代码之前被执行。

AutoCloseable对象的close方法中抛出异常

如果在AutoCloseable对象的close方法中抛出异常又会发生什么呢?运行一下代码看看:

public void close() throws Exception {
   System.out.println("The door is closed.");
   throw new CloseException(); 
}

输出:

The door is open.The door is becoming unhinged.The door is closed.Is there a draft? class CloseException
I'm putting a sweater on, regardless.

多个资源对象都抛出异常

上面的文章中我们了解到当try-with-resources的声明部分、方法体部分以及AutoCloseable对象的close方法抛出异常时,try-with-resources语句的执行规则。但是,如果有两个资源对象都抛出异常又会怎样呢?

先回到基础部分,我们知道我们在资源声明部分初始化多个资源对象,同样,我们知道如果资源对象正常初始化,那么他们也会被正常关闭(调用close方法)。

现在考虑一个问题,如果声明了两个资源对象,其中一个正常初始化,另一个却抛出异常会怎么发生什么?规则是:如果一个资源对象初始化正常,它的close方法会被调用,抛出异常的资源对象的close方法则不会被调用。

所以,假设我们增加了OpenWindow类:

class OpenWindow implements AutoCloseable {
    public OpenWindow() {
        System.out.println("The window is open.");
    }

    public void close() throws Exception {
        System.out.println("The window is closed.");
    }}

我们修改Man方法在OpenDoor对象前初始化一个OpenWindow对象实例,并且没有抛出异常,然后再初始化OpenDoor实例,OpenDoor将抛出异常,在这种情况下,正常初始化的OpenWindow对象的close方法会被调用,OpenDoor对象的close方法则不会被调用,输出如下:

The window is open.The door is open.The window is closed.Is there a draft? class OpenException
I'm putting a sweater on, regardless.

你可以看到,任何成功初始化的资源对象都会被正确关闭,反之则不会调用close方法仅会调用异常处理代码。

分享到:
评论

相关推荐

    javacv1.1-android-armARM

    3. **JavaCPP**:JavaCPP是一个库,它可以将C++的代码无缝集成到Java应用程序中,通过桥接Java和C++的内存管理,使得Java开发者可以直接使用C++库。在JavaCV中,JavaCPP用于调用OpenCV、FFmpeg等C++实现的底层库。 ...

    java-7-openjdk-arm64-aarch64.tar.gz

    Java 7 OpenJDK Arm64 AArch64 压缩包文件“java-7-openjdk-arm64-aarch64.tar.gz”是专为基于ARM架构的64位系统设计的Java开发运行环境。这个压缩包包含了OpenJDK 7的实现,OpenJDK是一个开源版本的Java开发工具包...

    ARM开发板配置java运行环境成功笔记记录

    在本文中,我们将深入探讨如何在ARM架构的开发板上配置Java运行环境,以便能够成功地执行Java测试代码。ARM开发板通常用于嵌入式系统和物联网(IoT)设备,而Java是一种广泛使用的编程语言,尤其适用于这些平台。下面...

    java8安装包_linux-arm版本.rar

    9. **使用与开发**: 安装完成后,你可以开始使用Java 8进行开发,运行Java应用程序,或者进一步学习Java 8的新特性,如lambda表达式、方法引用、流API和日期时间API等。 通过以上步骤,你可以在Linux ARM设备,如...

    Java17新特性详解含示例代码(值得珍藏)

    Java 17作为Java的最新版本,引入了一系列提升开发效率、性能和开发体验的新特性。以下是Java 17的主要新特性及其实现方式: 1. **增强的伪随机数生成器 (JEP 356)** Java 17引入了RandomGenerator接口和相关实现...

    ARM嵌入式系统基础教程PPT

    - 外围接口:探讨常见的ARM系统外设接口,如GPIO、UART、SPI和I2C等。 5. **其他章节(未提供)** - 可能涵盖的内容:中断和异常处理、嵌入式操作系统的选择与移植、软件开发环境的建立、嵌入式程序设计等。 这...

    Java1.8 Linux环境下 x86、x64 以及 arm架构的安装包 RPM格式 和 tar.gz格式 共6个文件

    - **Java 1.8**:Java 1.8,也称为Java 8,引入了Lambda表达式、函数式编程、新的日期时间API、改进的并发性能和Java虚拟机(JVM)优化等特性。它是Java SE(标准版)的一个关键版本,广泛应用于服务器端开发、桌面...

    ARM嵌入式系统基础教程

    ARM嵌入式系统基础教程是针对想要深入了解嵌入式领域,特别是ARM处理器技术的初学者设计的一套教学资源。ARM架构在全球嵌入式系统中占据了主导地位,广泛应用于移动设备、物联网、工业控制等多个领域。本教程将带你...

    jav ffmpeg arm转mp3 需要工具.rar

    - **资源管理**:确保FFmpeg进程在完成后被正确关闭,释放系统资源。 博客的安装教程可能会包括以下步骤: 1. **下载FFmpeg**:获取适用于ARM平台的FFmpeg二进制文件。 2. **配置环境变量**:将FFmpeg的bin目录...

    完整版 Java开发实训课程系列-Java高级应用编程 第6章 Java7新特性(共16页).ppt

    6. **自动资源管理(ARM)**:Java 7引入了自动资源管理,通过`try-with-resources`语句,可以确保在`try`块中的资源(如文件流或数据库连接)在不再需要时被正确关闭,即使在处理异常时也不例外。这提高了代码的...

    ARM9接口操作教程_word格式

    总结来说,ARM9接口操作教程将引导读者了解ARM9处理器的基础知识,包括其历史、架构特点、应用领域以及不同系列的特性。通过学习,读者可以有效地进行ARM9接口的操作和编程,为后续的嵌入式系统开发打下坚实基础。

    深入理解JVM内幕:从基本结构到Java 7新特性

    本文将深入探讨JVM的基本结构、执行流程,以及Java 7的新特性。 首先,JVM由Java API和JRE组成,其中JVM的主要职责是通过类加载器(Class Loader)加载Java程序,并根据Java API来执行这些程序。JVM的设计是基于栈...

    Java发展史_&_Java9、10新特性

    ### Java发展史与Java 9、10新特性详解 #### Java发展史 Java自1995年由Sun Microsystems发布以来,历经多个版本的发展和完善,成为当今最受欢迎的编程语言之一。下面简要回顾Java的发展历程及其重要里程碑: - *...

    ARM嵌入式系统基础教程(第二版)周立功

    ### ARM嵌入式系统基础教程知识点总结 #### 1. 嵌入式系统的概述 **1.1 嵌入式系统** - **嵌入式系统的定义:** - 技术角度:以应用为中心、以计算机技术为基础、软件硬件可裁剪、适应应用系统对功能、可靠性、...

    ARM入门教程和入门手册

    这个“ARM入门教程和入门手册”是为那些希望深入理解ARM技术的初学者准备的宝贵资源。以下是对这两份文档内容的详细概述。 **ARM嵌入式入门级教程** 这份PDF教程可能涵盖了以下几个核心主题: 1. **ARM架构基础**...

    广州周立功ARM培训教程7

    【标题】:“广州周立功ARM培训教程7” 在嵌入式系统的世界中,ARM处理器以其高效能、低功耗的特性,广泛应用于各种设备,从智能手机到物联网设备,无处不在。广州周立功公司在该领域享有盛誉,其提供的ARM培训教程...

    arm开发软件使用教程

    ARM开发软件使用教程主要...总之,这个教程会帮助学习者了解ARM开发的基本流程,从安装必要的开发工具,到理解S3C44B0X的硬件特性,再到编写和调试代码。通过实践,学习者将能够独立完成基于ARM平台的嵌入式系统开发。

    Java7 最新原版API

    1. **自动资源管理(Automatic Resource Management, ARM)**:引入了try-with-resources语句,使得资源(如文件流或数据库连接)能够更方便且安全地关闭,减少了手动管理资源可能导致的错误。 2. **多路复用器...

    ARM7的教程和keil for carm实例

    该手册可能会详细解释LPC微控制器的硬件特性,如引脚配置、存储器映射、外设接口等,以及如何进行系统级的设计和调试。 Keil uVision是常用的ARM开发工具,它包含了一个强大的IDE(集成开发环境),CARM是Keil为ARM...

Global site tag (gtag.js) - Google Analytics