版本特性

Java 各版本特性介绍

上古时代

Java 的最初发布简直是革命性的,但它并不标志着 Java 快速创新时代的结束。与大多数其他软件系统通常安于一种小规模、渐进式的改进模式不同,Java 继续以爆炸性的速度发展。在 Java 1.0 发布后不久,Java 的设计者就已经创造了 Java 1.1。Java 1.1 所增加的功能比小的修订数的增加更重要、更实质性。Java 1.1 增加了许多新的库元素,重新定义了事件的处理方式,并重新配置了 1.0 库的许多功能。它还废止了(使之过时)了 Java 1.0 最初定义的几个功能。因此,Java 1.1 既增加了原有规范的属性,也减少了原有规范的属性。

Java 的下一个重要版本是 Java 2,这里的 “2 “表示 “第二代”。Java 2 的诞生是一个分水岭,标志着 Java “现代时代 “的开始。Java 2 的第一个版本带有 1.2 的版本号。Java 2 的第一个版本使用了 1.2 的版本号,这似乎很奇怪。原因是它原本指的是 Java 库的内部版本号,但后来被泛指整个版本。随着 Java 2 的发布,Sun 公司将 Java 产品重新包装为 J2SE(Java 2 Platform Standard Edition),版本号开始应用于该产品。Java 2 增加了对一些新功能的支持,如 Swing 和 Collections Framework,它还增强了 Java 虚拟机和各种编程工具。Java 2 也包含了一些废弃的功能。最重要的影响了 Thread 类,其中方法 suspend( )、resume( )和 stop( )被废弃。

J2SE 1.3 是对原始 Java 2 版本的第一次重大升级。在大部分情况下,它增加了现有的功能,并 “收紧 “了开发环境。一般来说,为 1.2 版本编写的程序和为 1.3 版本编写的程序在源代码上是兼容的。虽然 1.3 版本包含的变化比前面三个主要版本要小,但它还是很重要。J2SE 1.4 的发布进一步增强了 Java。这个版本包含了几个重要的升级、增强和添加。例如,它增加了新的关键字 assert、链式异常和基于通道的 I/O 子系统。它还对 Collections Framework 和网络类进行了修改。此外,整个过程中还做了许多小改动。尽管有大量的新特性,1.4 版本仍然保持了与之前版本近乎 100%的源代码兼容性。

Java 的下一个版本是 J2SE 5,它是革命性的。与之前大多数的 Java 升级不同的是,J2SE 5 提供了重要的、但有分寸的改进,它从根本上扩展了该语言的范围、能力和范围。为了掌握 J2SE 5 对 Java 所做的改变的规模,请考虑下面的主要新特性列表。

  • 通用性
  • 附加说明
  • 自动装箱和自动开箱。
  • 枚举
  • 增强的 for-each 风格的循环
  • 可变长度的参数(varargs)
  • 静态导入
  • 格式化的 I/O
  • 并发实用程序

这不是一个小的调整或增量升级的清单。列表中的每一项都代表着对 Java 语言的重大补充。其中一些,如 generics、增强的 for 和 varargs,引入了新的语法元素。其他的,如自动装箱和自动拆箱,则改变了语言的语义。注释为编程增加了一个全新的维度。在所有情况下,这些新增功能的影响都超出了它们的直接作用。它们改变了 Java 本身的特性。

这些新特性的重要性体现在版本号 “5 “的使用上。Java 的下一个版本号通常应该是 1.5。然而,新特性是如此重要,以至于从 1.4 到 1.5 的转变似乎并不能表达变化的幅度。相反,Sun 选择将版本号增加到 5,以此来强调正在发生的重大事件。因此,它被命名为 J2SE 5,而开发者工具包则被称为 JDK 5。但是,为了保持一致性,Sun 公司决定使用 1.5 作为其内部版本号,这也被称为开发者版本号。J2SE 5 中的 “5 “被称为产品版本号。

Java 的下一个版本被称为 Java SE 6。Sun 再次决定更改 Java 平台的名称。首先,请注意,“2 “被去掉了。因此,该平台现在被命名为 Java SE,官方产品名称为 Java Platform, Standard Edition 6。Java 开发包被称为 JDK 6。与 J2SE 5 一样,Java SE 6 中的 6 是产品版本号。内部的,开发者版本号是 1.6。

Java SE 6 在 J2SE 5 的基础上,增加了渐进式的改进。Java SE 6 没有对 Java 语言本身增加任何重大的功能,但它确实增强了 API 库,增加了几个新的包,并对运行时提供了改进。在其(用 Java 术语来说)漫长的生命周期中,它也经历了几次更新,沿途增加了一些升级。总的来说,Java SE 6 进一步巩固了 J2SE 5 所取得的进步。

Java SE 7

Java SE 7 是 Java 的下一个版本,Java 开发工具包被称为 JDK 7,内部版本号为 1.7。Java SE 7 是 Sun Microsystems 被 Oracle 收购后的第一个主要的 Java 版本。Java SE 7 包含了许多新功能,包括对语言和 API 库的重大补充。还包括对支持非 Java 语言的 Java 运行时系统的升级,但 Java 程序员最感兴趣的是语言和库的增加。

新的语言功能是作为 Project Coin 的一部分开发的。Project Coin 的目的是确定一些将被纳入 JDK 7 的 Java 语言的小改动。虽然这些特性被统称为 “小”,但就其影响的代码而言,这些变化的影响却相当大。事实上,对于很多程序员来说,这些变化很可能是 Java SE 7 中最重要的新特性。以下是 JDK 7 增加的语言特性列表。

  • 一个字符串现在可以控制一个开关语句。
  • 二进制整数字元。
  • 数字字元中的下划线。
  • 扩展的 try 语句,称为 try-with-resources,支持自动资源管理。(例如,当不再需要流时,可以自动关闭它们。)
  • 当构造一个通用实例时,可进行类型推理(通过钻石运算符)。
  • 增强的异常处理,可以通过一次捕获(multi-catch)捕获两个或多个异常,并对重抛的异常进行更好的类型检查。
  • 虽然不是语法上的变化,但与某些类型的 varargs 方法相关的编译器警告得到了改进,你可以对警告进行更多的控制。

正如你所看到的,尽管 Project Coin 的特性被认为是对语言的小改动,但它们的好处要比 “小 “这个限定词所显示的大得多。尤其是,try-with-resources 语句深刻地影响了基于流的代码的编写方式。另外,使用 String 来控制 switch 语句的能力也是一个渴望已久的改进,它简化了许多情况下的编码。

Java SE 7 对 Java API 库做了一些补充。其中最重要的两个是对 NIO 框架的增强和增加了 Fork/Join 框架。NIO(最初代表 New I/O)是在 1.4 版本中加入 Java 的。然而,Java SE 7 所增加的变化从根本上扩展了它的功能。这些变化如此之大,以至于人们经常使用 NIO.2 这个术语。

Fork/Join 框架为并行编程提供了重要的支持。并行编程是有效利用包含一个以上处理器的计算机(包括多核系统)的技术的通常名称。多核环境带来的优势是程序性能有望大幅提升。Fork/Join 框架通过以下方式解决并行编程问题。

  • 简化可同时执行的任务的创建和使用。
  • 自动利用多个处理器

因此,通过使用 Fork/Join 框架,您可以轻松创建可扩展的应用程序,自动利用执行环境中可用的处理器。当然,并不是所有的算法都适合并行化,但对于那些适合并行化的算法,可以获得执行速度的显著提高。

Java SE 8 & 9

Java 的下一个版本是 Java SE 8,开发者工具包被称为 JDK 8。它的内部版本号为 1.8。JDK 8 是对 Java 语言的重大升级,因为它加入了一个影响深远的新语言特性:lambda 表达式。lambda 表达式的影响曾经并将继续深刻,它既改变了编程方案的概念化方式,也改变了 Java 代码的编写方式。正如第 15 章中详细解释的那样,lambda 表达式为 Java 增加了功能编程特性。在这个过程中,lambda 表达式可以简化和减少创建某些构造(如某些类型的匿名类)所需的源代码数量。lambda 表达式的加入也使得语言中增加了一个新的操作符(the->)和一个新的语法元素。

lambda 表达式的加入也对 Java 库产生了广泛的影响,为了利用它们而增加了新的功能。其中最重要的是新的流 API,它被打包在 java.util.stream 中。流 API 支持对数据的管道操作,并针对 lambda 表达式进行了优化。另一个新包是 java.util.function。它定义了许多功能接口,为 lambda 表达式提供了额外的支持。其他与 lambda 相关的新功能在整个 API 库中都能找到。

另一个受 lambda 启发的特性影响了接口。从 JDK 8 开始,现在可以为接口指定的方法定义一个默认实现。如果没有创建默认方法的实现,则使用接口定义的默认实现。这一特性使接口能够随着时间的推移而优雅地发展,因为可以在不破坏现有代码的情况下将新方法添加到接口中。当默认值合适时,它还可以简化接口的实现。JDK 8 中的其他新特性还包括新的时间和日期 API、类型注释以及在对一个数组进行排序时使用并行处理的能力等等。

Java 的下一个版本是 Java SE 9.开发者工具包被称为 JDK 9.随着 JDK 9 的发布,内部版本号也是 9.JDK 9 代表了一个重要的 Java 版本,包含了对 Java 语言及其库的重大改进。与 JDK 5 和 JDK 8 版本一样,JDK 9 也从根本上影响了 Java 语言及其 API 库。

JDK 9 的主要新功能是模块,它使您能够指定组成应用程序的代码的关系和依赖关系。模块还为 Java 的访问控制功能增加了另一个维度。模块的加入使得 Java 中增加了一个新的语法元素和几个关键字。此外,JDK 中还添加了一个名为 jlink 的工具,它使程序员能够创建一个只包含必要模块的应用程序的运行时映像。还创建了一种新的文件类型,称为 JMOD。模块还对 API 库产生了深刻的影响,因为从 JDK 9 开始,库包现在被组织成模块。

虽然模块构成了 Java 的重大改进,但它们在概念上是简单而直接的。此外,由于完全支持模块前的遗留代码,模块可以按照您的时间表集成到开发过程中。不需要立即改变任何已有的代码来处理模块。简而言之,模块在不改变 Java 本质的情况下增加了大量的功能。

除了模块之外,JDK 9 还包括许多其他新功能。其中特别值得关注的是 JShell,它是一个支持交互式程序实验和学习的工具。(JShell 的介绍见附录 B。)另一个有趣的升级是对私有接口方法的支持。它们的加入进一步增强了 JDK 8 对接口中默认方法的支持。JDK 9 在 javadoc 工具中增加了搜索功能,并增加了一个名为@index 的新标签来支持它。与以前的版本一样,JDK 9 包含了许多对 Java 的 API 库的增强。

一般来说,在任何一个 Java 版本中,最受关注的都是新功能。然而,Java 有一个备受瞩目的方面被 JDK 9 废弃了:小程序。从 JDK 9 开始,不再推荐新项目使用小程序。正如本章前面所解释的那样,由于浏览器对小程序支持的减弱(以及其他因素),JDK 9 废弃了整个小程序 API。

新的发布模式

2018 年 3 月 21 日,Oracle 官方宣布 Java 10 正式发布。这是 Java 大版本周期变化后的第一个正式发布版本。需要注意的是 Java 9 和 Java 10 都不是 LTS 版本。和过去的 Java 大版本升级不同,这两个只有半年左右的开发和维护期。而未来的 Java 11,也就是 18.9 LTS,才是 Java 8 之后第一个 LTS 版本。

/jdk-10/bin$ ./java -version

openjdk version "10" 2018-03-20

OpenJDK Runtime Environment 18.3 (build 10+46)

OpenJDK 64-Bit Server VM 18.3 (build 10+46, mixed mode)

这种发布模式已经得到了广泛应用,一个成功的例子就是 Ubuntu Linux 操作系统,在偶数年 4 月的发行版本为 LTS,会有很长时间的支持。如 2014 年 4 月份发布的 14.04 LTS,Canonical 公司和社区支持到 2019 年。类似的,Node.js,Linux kernel,Firefox 也采用类似的发布方式。

从 JDK 10 开始,Java 改为每 6 个月发布一个 feature release,这是 Java 适应云时代技术快速发展的另一个重要举措。过去一个主版本的发布需要 3 年甚至更久,使得很多社区期待但又不用很长时间就可以实现的特性,也不得不等待更久。6 个月一个版本,使得短平快的特性能够及时发布来满足开发者需求,同时对于大的复杂的特性又能够分解成小的可以发布的单元,及时获得社区的使用和反馈。在 6 个月一个版本的基础上,针对需要更加稳定的运行环境的企业客户,我们又提供 LTS 版本。这个新的 release 模式,使得 Java 能够同时满足两种不同类别用户的需求,更加有利于 Java 向前推进。

JDK 10 增加的主要新语言功能是支持本地变量类型推理。通过局部变量类型推理,现在可以让局部变量的类型从其初始化器的类型中推断出来,而不是显式指定。为了支持这种新的功能,Java 中增加了上下文敏感的标识符 var 作为保留类型名。类型推理可以简化代码,因为当一个变量的类型可以从它的初始化器中推断出来时,就不需要多余地指定它的类型。在类型难以辨别或无法明确指定的情况下,它还可以简化声明。本地变量类型推断已经成为当代编程环境中常见的一部分。它被包含在 Java 中,有助于使 Java 跟上语言设计的发展潮流。除了其他一些变化之外,JDK 10 还重新定义了 Java 版本字符串,改变了版本号的含义,使其更好地与新的基于时间的发布时间表保持一致。

未来

在撰写本文时,Java 的最新版本是 Java SE 11(JDK 11)。它于 2018 年 9 月发布,这比 JDK 10 晚了 6 个月。JDK 11 中主要的新语言特性是支持在 lambda 表达式中使用 var。除了对一般 API 的一些调整和更新,JDK 11 还增加了一个新的网络 API,这将是广大开发人员感兴趣的。它被称为 HTTP Client API,被打包在 java.net.http 中,它为 HTTP 客户端提供了增强、更新和改进的网络支持。另外,Java 启动器还增加了另一种执行模式,使其可以直接执行简单的单文件程序。JDK 11 还删除了一些功能。也许由于其历史意义,最引人关注的是删除了对小程序的支持。回顾一下,小程序最早是由 JDK 9 废弃的。随着 JDK 11 的发布,小程序的支持已经被移除。对另一项名为 Java Web Start 的部署相关技术的支持也已从 JDK 11 中删除。随着执行环境的不断发展,小程序和 Java Web Start 都迅速失去了意义。JDK 11 的另一个关键变化是,JavaFX 不再包含在 JDK 中。取而代之的是,这个 GUI 框架已经成为一个独立的开源项目。因为这些功能不再是 JDK 的一部分,所以本书没有讨论它们。

关于 Java 的发展,还有一点。从 2006 年开始,Java 的开源进程开始了。今天,JDK 的开源实现已经出现。开源进一步促进了 Java 开发的动态性。归根结底,Java 的创新遗产是安全的。Java 仍然是编程世界所期待的充满活力、灵活的语言。

本书中的材料已经针对 JDK 11 进行了更新。本书通篇描述了许多新的 Java 特性、更新和新增内容。然而,正如前面的讨论所强调的那样,Java 编程的历史是以动态变化为特征的。您将希望回顾每个后续 Java 版本中的新特性。简单地说:Java 的进化还在继续

Links