原文出处:http://shiq-stone.iteye.com/blog/1173980

Java7 中有一些令开发者很高兴的新特性,如switch语句中的使用字符串作为表达式,多catch异常处理,try-with-resources(自动资源管理),新的文件系统API, jvm扩展,支持动态类型语言,支持并行任务的fork/join框架,以及其他一些肯定会被社区支持的特性。

下面就概述以上功能,并提供适当的例子。这里可以下载一个zip文件,其中包含在这篇文章中的代码片段。

语言增强

Java7 通过提供了一些新的语言特性,这些功能对开发者来说非常方便。

Diamond Operator

你可能已经注意到在使用泛型的时候,IDE经常会出现警告提示。例如,如果我们要声明一个使用trades类作为泛型的Map类时,我们会写出像下面的代码:

Java代码  Map> trades = new TreeMap> ();

我们必须在等号两边都声明同样的类型,这并不是一件很方便的事情,显然右边的声明看上去有些多余。编译器能根据左边的声明推断右边的类型吗?之前是不行的,在Java7中的代码可以写成下面的样子:

Java代码  Map> trades = new TreeMap <> ();

是不是很酷?你不需要输入实例类型的完整列表。相反,你使用<>符号,这就是所谓的钻石操作符,请注意,虽然没有声明的钻石操作符是合法的, trades = new TreeMap () ),但它会使编译器生成几个类型安全警告。

在switch语句中使用的字符串

之前的switch语句只能使用原始数据类型或枚举类型。Java 7中引入另一种类型,我们可以在switch语句中使用字符串String类型。

假设我们需要根据状态处理一个交易,到现在为止,我们使用if - else语句。

Java代码  private void processTrade(Trade t) {

String status = t.getStatus();

if (status.equalsIgnoreCase(NEW)) {

newTrade(t);

} else if (status.equalsIgnoreCase(EXECUTE)) {

executeTrade(t);

} else if (status.equalsIgnoreCase(PENDING)) {

pendingTrade(t);

}

}

这是一种很粗糙的处理方法,在Java 7中,我们可以利用增强的switch语句,使用String作为参数

Java代码  public void processTrade(Trade t) {

String status = t.getStatus();

switch (status) {

case NEW:

newTrade(t);

break;

case EXECUTE:

executeTrade(t);

break;

case PENDING:

pendingTrade(t);

break;

default:

break;

}

}

在上面的程序中,状态字段总是使用String.equals()方法和case标签进行比较。

Automatic resource management

像连接、文件、I/O流一些的资源都需要开发者编写代码手动的关闭,通常我们使用try-finally块负责关闭各自的资源。目前常用的实现如下:

Java代码  public void oldTry() {

try {

fos = new FileOutputStream("movies.txt");

dos = new DataOutputStream(fos);

dos.writeUTF("Java 7 Block Buster");

} catch (IOException e) {

e.printStackTrace();

} finally {

try {

fos.close();

dos.close();

} catch (IOException e) {

// log the exception

}

}

}

然而,Java 7中引入了另一个很酷的功能,自动管理资源。 它操作非常简单。 我们要做的是在try中声明资源,如下:

Java代码  try(resources_to_be_cleant){

// your code

}

前面的方法oldtry可以使用新功能改写成如下:

Java代码  public void newTry() {

try (FileOutputStream fos = new FileOutputStream("movies.txt");

DataOutputStream dos = new DataOutputStream(fos)){

dos.writeUTF("Java 7 Block Buster");

}catch (IOException e) {

// log the exception

}

}

上面的代码,也代表此功能的另一个方面:与多个资源的工作。 FileOutputStream和DataOutputStream资源都包含在try语句中一前一后,每一个资源分别由分号分隔(;)。我们不需要去手动的废除或关闭资源,它们会在控制推出try语言块后自动的在后台关闭。需要被自动关闭的资源必须实现java.lang.AutoCloseable接口。

任何实现AutoCloseable接口的资源都会被作为自动资源管理的对象,AutoCloseable是java.io.Closeable接口的父类,只有close()一个方法,当程序控制推出try语言块时,该方法会被jvm调用。

数字文字用下划线

数值文字是眼睛过滤器。如果给你一个带有十个零的数,我相信你一定会像我一样的开始计算零的个数。识别一个百万甚至千万的数是很容易出错,而且繁琐的。在Java7中可以再确定的地方引入强调符号,例如你可以像下面的方式声明一千:

Java代码  int thousand =  1_000;

或者一百万

Java代码  int million  =  1_000_000

注意:此版本也引入了binary二进制文字,开发人员再也不必将它们转换为十六进制了,例如“0B1”。

改进的异常处理

在异常处理方面也有一些改进。Java7引入了多重捕获功能(multi-catch),可以再一个catch块中捕获多种不同类型的异常。

例如,你有一个方法会抛出三个异常,按之前的处理,你需要像下面这样分别处理各个异常:

Java代码  public void oldMultiCatch() {

try {

methodThatThrowsThreeExceptions();

} catch (ExceptionOne e) {

// log and deal with ExceptionOne

} catch (ExceptionTwo e) {

// log and deal with ExceptionTwo

} catch (ExceptionThree e) {

// log and deal with ExceptionThree

}

}

在catch块中捕获一个又一个的异常,看起来非常杂乱。如代码所示捕获一堆异常,效率非常低下,而且容易出错。Java 7中带来了一种新的语言变化,来解决这个丑小鸭。来看看方法的改进版本oldMultiCatch方法如下:

Java代码  public void newMultiCatch() {

try {

methodThatThrowsThreeExceptions();

} catch (ExceptionOne | ExceptionTwo | ExceptionThree e) {

/ log and deal with all Exceptions

}

}

多个异常在一个catch块中捕获,不同的异常之间用(|)操作符分隔开。使用这种方法你就不需要写许多的捕获异常块。而且,如果你有许多属于不同类型的异常,你可以使用多个multi-catch块,下面的代码片段说明了这一点:

Java代码  public void newMultiMultiCatch() {

try {

methodThatThrowsThreeExceptions();

} catch (ExceptionOne e) {

// log and deal with ExceptionOne

} catch (ExceptionTwo | ExceptionThree e) {

// log and deal with ExceptionTwo and ExceptionThree

}

}

在上述案例中,ExceptionTwo和ExceptionThree属于不同层次,所以你会想用一个catch块的不同方法来处理它们。

新的文件系统API (NIO 2.0)

使用过Java IO的人可能任然记得框架带来的麻烦。跨操作系统或者多文件系统的无缝使用从来都不一件容易的事情。像删除文件、重命名一类的动作在很多时候都会引起不可意料的结果。使用符号链接是另一个问题。总地来说,API需要大修。

为了解决上述Java的IO问题,Java 7的推出了新的API。NIO 2.0带来了许多新的改进,也引入了新的类,方便开发人员处理多文件系统问题。

文件路径

新java.nio.file的包中包含Path,Paths ,FileSystem,FileSystems和其他如类和接口。

Path是一个简单的引用文件的路径。 它是等价(更多的功能) java.io.File 。 下面的代码片断演示了如何获得“Temp”文件夹的路径引用:

Java代码  public void pathInfo() {

Path path = Paths.get("c:\\Temp\\temp");

System.out.println("Number of Nodes:" + path.getNameCount());

System.out.println("File Name:" + path.getFileName());

System.out.println("File Root:" + path.getRoot());

System.out.println("File Parent:" + path.getParent());

}

控制台会输出如下内容:

Console代码  Number of Nodes:2

File Name:temp.txt

File Root:c:\

File Parent:c:\Temp

删除一个文件或目录只需要简单的调Files类的delete方法(注意复数)。 Files类公开了两个delete方法,其中一个会抛出NoSuchFileException另一个则不会。

下面的删除方法调用抛出NoSuchFileException的,所以你必须处理它:

Java代码  Files.delete(path);

如果文件或目录不存在,Files.deleteIfExists(path)不会抛出异常。

您可以使用Files.copy(..)和Files.move(..)等通用方法对文件系统进行操作。 同样,使用createSymbolicLink(..)方法创建符号链接。

文件更改通知

在JDK 7,我最喜欢的改善之一,是增加了文件更改通知。 这一直是期待已久的的功能,终于雕刻成NIO 2.0。WatchService API使你会在对象(目录或文件)变化后收到事件通知。

实现API所涉及的步骤是:

·创建一个WatchService。 这项服务包括一个持有WatchKeys的队列

·用这个WatchService注册要监视的目录/文件

·注册时,指定您希望收到的事件的类型(创建,修改或删除事件)

·开始一个无限循环监听事件

·当事件发生时,一个WatchKey被放入队列

·消耗WatchKey,并调用它的查询

通过一个例子。我们创建一个DirPoliceJava程序,其责任是检测一个特定的目录。步骤如下:

1、创建WatchService对象:

Java代码  WatchService  watchService = FileSystems.getDefault().newWatchService();

2、获取到你监视的目录的路径引用。我建议你把这个目录的参数化,所以你不要硬编码文件名;

Java代码  path = Paths.get("C:\\Temp\\temp\\");

3、下一步是用WatchService为该目录注册所有类型的事件:

Java代码  dirToWatch.register(watchService, ENTRY_CREATE, ENTRY_MODIFY, ENTRY_DELETE);

这是java.nio.file.StandardWatchEventKind事件类型

4、启动无限循环,并开始接受的事件:

Java代码  while(true){

WatchKey key = watchService.take(); // this would return you keys

}

5、通过对关键事件的运行:

Java代码  for(WatchEvent> event : key.pollEvents()) {

Kind> kind = event.kind();

System.out.println("Event on " + event.context().toString() + " is " + kind);

}

例如,如果你修改或删除这个临时文件夹,你会在控制台看到入下输出:

Console代码  Event on temp is ENTRY_MODIFY

Event on temp is ENTRY_DELETE

DirPolice相关方法源代码如下(下载完整的源代码):

Java代码  try {

watchService = FileSystems.getDefault().newWatchService();

path.register(watchService, ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY);

} catch (IOException e) {

System.out.println("IOException"+ e.getMessage());

}

Java代码  /**

* The police will start making rounds

*/

private void doRounds() {

WatchKey key = null;

while(true) {

try {

key = watchService.take();

for(WatchEvent> event : key.pollEvents()) {

Kind> kind = event.kind();

System.out.println("Event on " + event.context().toString() + " is " + kind);

}

} catch (InterruptedException e) {

System.out.println("InterruptedException: "+e.getMessage());

}

boolean reset = key.reset();

if(!reset)

break;

}

}

Fork and Join

在java程序中有效的使用并行内核一直是一个挑战,有一些框架将任务分派到多核上执行,然后合并返回的结果集。Java7纳入这个功能,提供一个fork/join框架。

总地来说,Fork-Join把待处理的任务逐级分解成小任务,直到所有任务都已经足够简单不需要再分解。它就像一个分治算法。这个框架中的一个重要的概念是最好没有工作线程处于空闲状态。它实现了工作-窃取算法,空闲线程会从繁忙的工作线程处“窃取”任务。

支持fork-join机制的核心类是ForkJoinPool和ForkJoinTask。ForkJoinPool基本上是一个ExecutorService的特别实现类,执行我们上面谈到的工作窃取算法。

我们创建一个ForkJoinPool的实例,提供目标并行级别——处理器的数量,如下所示:

Java代码  ForkJoinPool pool = new ForkJoinPool(numberOfProcessors)

numberOfProcessors = Runtime.getRunTime().availableProcessors();

但是,默认的ForkJoinPool实例需要设置并行级别为上面获得相同数量。

需要解决的问题写在ForkJoinTask里。 但是,有两个实现类:RecursiveAction和RecursiveTask,这两个类之间的唯一区别是,前者不返回值,而后者则返回指定类型的对象。

以下是如何创建RecursiveTask或RecursiveAction处理前面提到的问题(我使用 RecursiveAction类)

Java代码  public class MyBigProblemTask extends RecursiveAction {

@Override

protected void compute() {

. . . // your problem invocation goes here

}

}

你必须覆盖需要提供计算功能的方法。 现在,向Executor提供ForkJoinTask,通过调用ForkJoinPool的invoke方法:

Java代码  pool.invoke(task);

支持动态语言

Java是一种静态类型的语言——变量,方法和返回值的类型检查是在编译时进行。 JVM在运行时执行强类型的字节码,而不必担心找到的类型信息。

还有另一种类型的语言品种 - 动态语言。 Ruby,Python和Clojure的都属于这一类。 类型信息在运行时才能确定。 这是不是可能在Java,因为它不会有任何必要的类型信息。

Java 7中,推出的一项称为invokedynamic的新功能。 这使得虚拟机的变化,纳入非Java语言的要求。已经创建了一个新的软件包, java.lang.invoke , MethodHandle , CallSite和其他人组成的,如类,扩展动态语言的支持。

java7 diamond_Java 7 中的新功能相关推荐

  1. drx功能开启后_简单实用!小米手机中这些新功能真香

    小米手机作为国产机热销品牌之一,它除了有好看的外观,还有很多隐藏的实用功能,今天小编就来和大家分享5个小米手机里你不知道的功能. Al电话助理 看到陌生号码时,很多人第一反应就是挂掉,不想接听,但又担 ...

  2. SQLSERVER2014中的新功能

    SQLSERVER2014中的新功能 转载自:http://blog.csdn.net/maco_wang/article/details/22701087 博客人物:maco_wang SQLSER ...

  3. java中怎样定义实数_Java Math 类中的新功能,第 1 部分: 实数

    在这篇由两部分组成的文章中,Elliotte Rusty Harold 与您一起探讨经典 java.lang.Math 类中的"新"功能.第 1 部分主要讨论比较单调的数学函数.第 ...

  4. Windows Server 2012 DHCP 服务器中的新功能:故障转移和策略

    Windows Server 2012 DHCP 服务器中的新功能如下: DHCP 故障转移:此功能提供让两个 DHCP 服务器服务于 同一子网或作用域的 IP 地址和选项配置的能力,前提是 DHCP ...

  5. spring 5.x(1)-----Spring Framework 5.x中的新功能

    Spring Framework 5.x中有什么新功能 5.1版中的新功能 一般核心修订 基础设施: 在类路径和模块路径上对JDK 11的无警告支持. 支持Graal原生图像约束(反射,参数名称). ...

  6. Java平台,标准版Oracle JDK 9中的新功能

    Java平台,标准版 Oracle JDK 9中的新增功能 版本9 E77563-05 2017年9月 JDK 9中的新功能概述 Java Platform,Standard Edition 9是一个 ...

  7. bit1618c 功能简介_c 9中的新功能简介

    bit1618c 功能简介 With the upcoming release of .NET 5 - the release which unifies the .NET runtimes - Mi ...

  8. Java 11中的新功能和API详解系列1

    Java 11中的新功能和API详解系列1 2018.9.27 版权声明:本文为博主chszs的原创文章,未经博主允许不得转载. JDK 11在语言语法方面有一个小改动,增加了相当数量的新API,以及 ...

  9. PhotoZoom Classic 7中的新功能

    众所周知PhotoZoom Classic是家庭使用理想的放大图像软件.目前很多用户还在使用PhotoZoom Classic 6,对于PhotoZoom Classic 7还是有点陌生.其实在6代衍 ...

最新文章

  1. Android 面试题目之 线程池
  2. Java多线程闲聊(二):活锁和死锁
  3. 二十五、深入Java中的static静态修饰符
  4. Centos7 Zookeeper
  5. ubuntu12.04 安装中文输入法
  6. 用Emacs进行Java开发
  7. SQL Server 2008存储结构之GAM、SGAM
  8. 文字围绕浮动元素的妙用(HTML、CSS)
  9. 【2021牛客暑期多校训练营4】Average (二分答案,区间/子数组最大平均值,)
  10. 自定义Promise
  11. Overfeat论文笔记
  12. 华为鸿蒙系统支持什么手机_华为鸿蒙系统支持的手机型号_鸿蒙系统支持华为哪几款手机...
  13. 怎么将计算机的触摸鼠标锁定,终极:如何在笔记本电脑上锁定触摸鼠标
  14. 网站被劫持勒索怎么办
  15. macOS开发中用TagLib获取、修改音频文件信息
  16. 夜神模拟器连接手柄无反应_夜神安卓模拟器怎么连接手柄 夜神模拟器连接手柄教程...
  17. android波浪动画简书,Android贝塞尔曲线————波浪效果(大波浪)
  18. 位图(BMP)文件格式(一)
  19. 医院管理系统mysql课程设计_数据库(课程设计)报告(医院管理系统).doc
  20. 2、Prism的使用一

热门文章

  1. 一个合格程序员的标准
  2. 转载:WPF binding
  3. 有用的收藏!javascript/c#/asp.net
  4. 使用easyexcel导出时行高不自动调整的解决
  5. 使用计算机正确开机方法,电脑开关机的正确步骤
  6. hive 把mysql语句执行_R分别连接mysql hive执行操作
  7. Appium 夜神 配置
  8. 从0到1上线一个微信小程序
  9. 十二、十三天总结笔记
  10. cocos2d-x 3.0 画图节点——Node