回顾Java 8 9 10的新特性,展望即将来临的11和明年的12【大牛经验】

回顾Java 8 9 10的新特性,展望即将来临的11和明年的12【大牛经验】

Java12将于2019年3月发布,你是不是还没有开始在用8,

小编整理下8以后版本的新特性,供你参考


各版本发布时间:

1990年初,最初被命名为Oak;

1995年5月23日,Java语言诞生;

1996年1月,第一个JDK-JDK1.0诞生;

1996年4月,10个最主要的操作系统供应商申明将在其产品中嵌入Java技术;

1996年9月,约8.3万个网页应用了Java技术来制作;

1997年2月18日,JDK1.1发布;

1997年4月2日,JavaOne会议召开,参与者逾一万人,创当时全球同类会议纪录;

1997年9月,JavaDeveloperConnection社区成员超过十万;

1998年2月,JDK1.1被下载超过2,000,000次;

1998年12月8日,Java 2企业平台J2EE发布;

1999年6月,SUN公司发布Java三个版本:标准版(J2SE)、企业版(J2EE)和微型版(J2ME);

2000年5月8日,JDK1.3发布;

2000年5月29日,JDK1.4发布;

2001年6月5日,Nokia宣布到2003年将出售1亿部支持Java的手机;

2001年9月24日,J2EE1.3发布;

2002年2月26日,J2SE1.4发布,此后Java的计算能力有了大幅提升;

2004年9月30日,J2SE1.5发布,成为Java语言发展史上的又一里程碑。为了表示该版本的重要性,J2SE1.5更名为Java SE 5.0;

2005年6月,JavaOne大会召开,SUN公司公开Java SE 6。此时,Java的各种版本已经更名,以取消其中的数字“2”:J2EE更名为Java EE,J2SE更名为Java SE,J2ME更名为Java ME;

2006年12月,SUN公司发布JRE6.0;

2009年4月20日,甲骨文以74亿美元的价格收购SUN公司,取得java的版权,业界传闻说这对Java程序员是个坏消息(其实恰恰相反);

2010年11月,由于甲骨文对Java社区的不友善,因此Apache扬言将退出JCP;

2011年7月28日,甲骨文发布Java SE 7;

2014年3月18日,甲骨文发表Java SE 8;

2017年7月,甲骨文发表Java SE 9。

2018年3月21日,甲骨文发表Java SE 10。

2018年9月25日,甲骨文发表Java SE 11.

2019年3月,甲骨文将发表Java SE 12。


JDK 8 中的新特性

Java Platform, Standard Edition 8 是一个拥有丰富特性的主要版本。本文档总结了 Java SE 8、JDK 8 以及 Oracle 的 Java SE 8 实现中的特性和增强。单击组件名称可获取该组件增强功能更详细的描述。

  • Java 编程语言
    • Lambda 表达式是一个新的语言特性,已经在此版本中引入。该特性让您可以将功能视为方法参数,或者将代码视为数据。使用 Lambda 表达式,您可以更简洁地表示单方法接口(称为功能接口)的实例。
    • 方法引用为已经具有名称的方法提供了易于理解的 lambda 表达式。
    • 默认方法允许将新功能添加到库的接口中,并确保与为这些接口的旧版本编写的代码的二进制兼容性。
    • 重复批注支持对同一个声明或类型的使用多次应用相同的批注类型。
    • 类型批注支持在使用类型的任何地方应用批注,而不仅限于声明。与可插拔类型系统结合使用时,此特性可改进代码的类型检查。
    • 改进类型推断。
    • 方法参数反射。
  • 集合
    • 新的 java.util.stream 包中的类提供了一个 Stream API,支持对元素流进行函数式操作。Stream API 集成在 Collections API 中,可以对集合进行批量操作,例如顺序或并行的 map-reduce 转换。
    • 针对存在键冲突的 HashMap 的性能改进
  • 紧凑 profile包含 Java SE 平台的预定义子集,并且支持不需要在小型设备上部署和运行整个平台的应用。
  • 安全性
    • 默认启用客户端 TLS 1.2
    • AccessController.doPrivileged 的新变体支持代码断言其权限的子集,而不会阻止完全遍历堆栈来检查其他权限
    • 更强大的基于密码的加密算法
    • JSSE 服务器端支持 SSL/TLS 服务器名称指示 (SNI) 扩展
    • 支持 AEAD 算法:SunJCE 提供程序得到了增强,支持 AES/GCM/NoPadding 密码实现以及 GCM 算法参数。而且 SunJSSE 提供程序也得到了增强,支持基于 AEAD 模式的密码套件。请参阅 Oracle 提供程序文档,JEP 115。
    • 密钥库增强,包括新的域密钥库类型 java.security.DomainLoadStoreParameter 和为 keytool 实用程序新增的命令选项 -importpassword
    • SHA-224 消息摘要
    • 增强了对 NSA Suite B 加密的支持
    • 更好地支持高熵随机数生成
    • 新增了 java.security.cert.PKIXRevocationChecker 类,用于配置 X.509 证书的撤销检查
    • 适用于 Windows 的 64 位 PKCS11
    • Kerberos 5 重放缓存中新增了 rcache 类型
    • 支持 Kerberos 5 协议转换和受限委派
    • 默认禁用 Kerberos 5 弱加密类型
    • 适用于 GSS-API/Kerberos 5 机制的未绑定 SASL
    • 针对多个主机名称的 SASL 服务
    • JNI 桥接至 Mac OS X 上的原生 JGSS
    • SunJSSE 提供程序中支持更强大的临时 DH 密钥
    • JSSE 中支持服务器端加密套件首选项自定义
  • JavaFX
    • 本版本中实施了新的 Modena 主题。
    • 新的 SwingNode 类允许开发人员将 Swing 内容嵌入到 JavaFX 应用中。请参阅 SwingNode javadoc 和将 Swing 内容嵌入 JavaFX 应用中。
    • 新的 UI 控件包括 DatePickerTreeTableView 控件。
    • javafx.print 程序包为 JavaFX Printing API 提供了公共类。
    • 3D 图形特性现在包括 3D 形状、摄像头、灯光、子场景、材料、挑选和抗锯齿。JavaFX 3D 图形库中新增了 Shape3DBoxCylinderMeshViewSphere 子类)、SubSceneMaterialPickResultLightBaseAmbientLightPointLight子类)和 SceneAntialiasing API 类。此版本中的 Camera API 类也已更新。请参阅 javafx.scene.shape.Shape3Djavafx.scene.SubScenejavafx.scene.paint.Materialjavafx.scene.input.PickResultjavafx.scene.SceneAntialiasing 类的相关 javadoc 以及 JavaFX 3D 图形入门文档。
    • WebView 类包含新特性和改进。有关其他 HTML5 特性(包括 Web 套接字、Web 辅助进程和 Web 字体)
    • 增强了文本支持,包括双向文本、复杂文本脚本(如泰语和印地语控件)以及文本节点中的多行多样式文本。
    • 此版本添加了对 Hi-DPI 显示的支持。
    • CSS Styleable* 类已成为公共 API。有关更多信息,请参阅 Javafx.css javadoc。
    • 新的 ScheduledService 类允许自动重新启动服务。
    • JavaFX 现在可用于 ARM 平台。适用于 ARM 的 JDK 包含 JavaFX 的基础组件、图形组件和控制组件。
  • 工具
    • javadoc 工具支持新的 DocTree API,让您可以将 Javadoc 注释作为抽象语法树来进行遍历。
    • javadoc 工具支持新的 Javadoc Access API,让您可以直接从 Java 应用中调用 Javadoc 工具,而无需执行新的进程。
    • javadoc 工具现在支持检查 javadoc 注释的内容,从而避免在运行 javadoc 时生成的文件中产生各种问题,例如无效的 HTML 或可访问性问题。此特性默认为启用状态,可以通过新的 -Xdoclint 选项加以控制。有关更多详细信息,请参阅运行“javadoc -X”时的输出。javac 工具也支持此特性,但默认情况下并未启用它。
    • javac 命令的 -parameters 选项可用于存储正式参数名称,并启用反射 API 来检索正式参数名称。
    • javac 命令现已正确实施了 Java 语言规范 (JLS) 第 15.21 节中的相等运算符的类型规则。
    • javac 工具现在支持检查 javadoc 注释的内容,从而避免在运行 javadoc 时生成的文件中产生各种问题,例如无效的 HTML 或可访问性问题。可通过新的 Xdoclint 选项来启用此特性。有关更多详细信息,请参阅运行“javac-X”时的输出。此特性也可以在 javadoc 工具中使用,并且默认启用。
    • javac 工具现在支持根据需要生成原生标头。这样便无需在构建管道中单独运行 javah 工具。可以使用新的 -h 选项在 javac 中启用此特性,该选项用于指定写入头文件的目录。将为任何具有原生方法或者使用 java.lang.annotation.Native 类型的新批注的类进行批注的常量字段生成头文件。
    • 可通过 jjs 命令来调用 Nashorn 引擎。
    • java 命令用于启动 JavaFX 应用。
    • 重新编写了 java 手册页。
    • 可通过 jdeps 命令行工具来分析类文件。
    • Java Management Extensions (JMX) 支持远程访问诊断命令。
    • jarsigner 工具提供了一个选项用于请求获取时间戳机构 (TSA) 的签名时间戳。
    • Javac 工具
    • Javadoc 工具
  • 国际化
    • Unicode 增强,包括对 Unicode 6.2.0 的支持
    • 采用 Unicode CLDR 数据和 java.locale.providers 系统属性
    • 新增日历和区域设置 API
    • 支持将自定义资源包作为扩展进行安装
  • 部署
    • 现在可以使用 URLPermission 允许沙盒小程序和 Java Web Start 应用连接回启动它们的服务器。不再授予 SocketPermission
    • 在所有安全级别,主 JAR 文件的 JAR 文件清单中都需要 Permissions 属性。
  • Date-Time 程序包 — 一组新程序包,提供全面的日期-时间模型。
  • 脚本编写
    • Rhino Javascript 引擎已被替换为 Nashorn JavaScript 引擎
  • Pack200
    • Pack200 支持 JSR 292 引入的常量池条目和新字节码
    • JDK8 支持 JSR-292、JSR-308 和 JSR-335 指定的类文件更改
  • IO 和 NIO
    • 全新的基于 Solaris 事件端口机制的面向 Solaris 的 SelectorProvider 实现。要使用它,请将系统属性 java.nio.channels.spi.Selector 的值设置为 sun.nio.ch.EventPortSelectorProvider
    • 减小 <JDK_HOME>/jre/lib/charsets.jar 文件的大小
    • 提高了 java.lang.String(byte[], *) 构造函数和 java.lang.String.getBytes() 方法的性能。
  • java.lang 和 java.util 程序包
    • 并行数组排序
    • 标准编码和解码 Base64
    • 无符号算术支持
  • JDBC
    • 删除了 JDBC-ODBC Bridge。
    • JDBC 4.2 引入了新特性。
  • Java DB
    • JDK 8 包含 Java DB 10.10。
  • 网络
    • 已添加 java.net.URLPermission 类。
    • java.net.HttpURLConnection 类中,如果安装了安全管理器,那么请求打开连接的调用需要权限。
  • 并发性
    • java.util.concurrent 程序包中新增了一些类和接口。
    • java.util.concurrent.ConcurrentHashMap 类中新增了一些方法,支持基于新增流工具和 lambda 表达式的聚合操作。
    • java.util.concurrent.atomic 程序包中新增了一些类来支持可扩展、可更新的变量。
    • java.util.concurrent.ForkJoinPool 类中新增了一些方法来支持通用池。
    • 新增的 java.util.concurrent.locks.StampedLock 类提供了一个基于能力的锁,可通过三种模式来控制读/写访问。
  • Java XML - JAXP
  • HotSpot
    • 新增的硬件内部函数以便使用高级加密标准 (AES)。UseAESUseAESIntrinsics 标志用于为 Intel 硬件启用基于硬件的 AES 内部函数。硬件必须是 2010 年或更新的 Westmere 硬件。例如,要启用硬件 AES,请使用以下标志: -XX:+UseAES -XX:+UseAESIntrinsics 要禁用硬件 AES,请使用以下标志: -XX:-UseAES -XX:-UseAESIntrinsics
    • 删除了 PermGen。
    • 方法调用的字节码指令支持 Java 编程语言中的默认方法。
  • Java Mission Control 5.3 版本说明
    • JDK 8 包含 Java Mission Control 5.3。

JDK9的新特性

(一):jdk和jre的改变

JDK和JRE已经在Java SE 9中进行了模块化处理。在Java SE 9之前,JDK构建系统用于生成两种类型的运行时映像 ——Java运行时环境(JRE)和Java开发工具包(JDK)。 JRE是Java SE平台的完整实现,JDK包含了JRE和开发工具和类库。 可下图显示了Java SE 9之前的JDK安装中的主目录。JDK_HOME是安装JDK的目录。 如果你只安装了JRE,那么你只有在jre目录下的目录。

在 Java SE 9之前,JDK中: bin目录用于包含命令行开发和调试工具,如javac,jar和javadoc。 它还用于包含Java命令来启动Java应用程序。 include目录包含在编译本地代码时使用的C/C++头文件。 lib目录包含JDK工具的几个JAR和其他类型的文件。 它有一个tools.jar文件,其中包含javac编译器的Java类。 jre\bin目录包含基本命令,如java命令。 在Windows平台上,它包含系统的运行时动态链接库(DLL)。 jre\lib目录包含用户可编辑的配置文件,如.properties和.policy文件。 jre\lib\approved目录包含允许使用标准覆盖机制的JAR。 这允许在Java社区进程之外创建的实施标准或独立技术的类和接口的更高版本被并入Java平台。 这些JAR被添加到JVM的引导类路径中,从而覆盖了Java运行时中存在的这些类和接口的任何定义。 jre\lib\ext目录包含允许扩展机制的JAR。 该机制通过扩展类加载器(该类加载器)加载了该目录中的所有JAR,该引导类加载器是系统类加载器的子进程,它加载所有应用程序类。 通过将JAR放在此目录中,可以扩展Java SE平台。 这些JAR的内容对于在此运行时映像上编译或运行的所有应用程序都可见。 jre\lib目录包含几个JAR。 rt.jar文件包含运行时的Java类和资源文件。 许多工具依赖于rt.jar文件的位置。 jre\lib目录包含用于非Windows平台的动态链接本地库。 jre\lib目录包含几个其他子目录,其中包含运行时文件,如字体和图像。

Java SE 9调整了JDK的目录层次结构,并删除了JDK和JRE之间的区别。 下图显示了Java SE 9中JDK安装的目录。JDK 9中的JRE安装不包含include和jmods目录。

在Java SE 9 的JDK中: 没有名为jre的子目录。 bin目录包含所有命令。 在Windows平台上,它继续包含系统的运行时动态链接库。 conf目录包含用户可编辑的配置文件,例如以前位于jre\lib目录中的.properties和.policy文件。 include目录包含要在以前编译本地代码时使用的C/C++头文件。 它只存在于JDK中。 jmods目录包含JMOD格式的平台模块。 创建自定义运行时映像时需要它。 它只存在于JDK中。 legal 目录包含法律声明。 lib目录包含非Windows平台上的动态链接本地库。 其子目录和文件不应由开发人员直接编辑或使用。

(二):访问资源

资源是应用程序使用的数据,例如图像,音频,视频,文本文件等。Java提供了一种通过在类路径上定位资源来访问资源的位置无关的方式。 需要与在JAR中打包类文件相同的方式打包资源,并将JAR添加到类路径。 通常,类文件和资源打包在同一个JAR中。 访问资源是每个Java开发人员执行的重要任务。

1. 在JDK 9之前访问资源

在Java代码中,资源由资源名称标识,资源名称是由斜线(/)分隔的一串字符串。 对于存储在JAR中的资源,资源名称仅仅是存储在JAR中的文件的路径。 例如,在JDK 9之前,存储在rt.jar中的java.lang包中的Object.class文件是一个资源,其资源名称是java/lang/Object.class。 在JDK 9之前,可以使用以下两个类中的方法来访问资源: java.lang.Class java.lang.ClassLoader 资源由ClassLoader定位。 一个Class代理中的资源寻找方法到它的ClassLoader。 因此,一旦了解ClassLoader使用的资源加载过程,将不会在使用Class类的方法时遇到问题。 在两个类中有两种不同的命名实例方法: URL getResource(String name) InputStream getResourceAsStream(String name) 两种方法都会以相同的方式找到资源。 它们的差异仅在于返回类型。 第一个方法返回一个URL,而第二个方法返回一个InputStream。 第二种方法相当于调用第一种方法,然后在返回的URL对象上调用openStream()。 ClassLoader类包含三个额外的查找资源的静态方法: static URL getSystemResource(String name) static InputStream getSystemResourceAsStream(String name) static Enumeration<URL> getSystemResources(String name) 这些方法使用系统类加载器(也称为应用程序类加载器)来查找资源。 第一种方法返回找到的第一个资源的URL。 第二种方法返回找到的第一个资源的InputStream。 第三种方法返回使用指定的资源名称找到的所有资源的URL枚举。 要找到资源,有两种类型的方法可以从——getSystemResource*和getResource*中进行选择。 在讨论哪种方法是最好的之前,重要的是要了解有两种类型的资源: 系统资源 非系统资源 你必须了解他们之间的区别,以了解资源查找机制。系统资源是在bootstrap类路径,扩展目录中的JAR和应用程序类路径中找到的资源。非系统资源可以存储在除路径之外的位置,例如在特定目录,网络上或数据库中。 getSystemResource()方法使用应用程序类加载程序找到一个资源,委托给它的父类,它是扩展类加载器,后者又委托给它的父类(引导类加载器)。如果你的应用程序是独立的应用程序,并且它只使用三个内置的JDK类加载器,那么你将很好的使用名为getSystemResource *的静态方法。它将在类路径中找到所有资源,包括运行时映像中的资源,如rt.jar文件。如果你的应用程序是在浏览器中运行的小程序,或在应用程序服务器和Web服务器中运行的企业应用程序,则应使用名为getResource*的实例方法,它可以使用特定的类加载器来查找资源。如果在Class对象上调用getResource*方法,则会使用当前类加载器(加载Class对象的类加载器)来查找资源。 传递给ClassLoader类中所有方法的资源名称都是绝对的,它们不以斜线(/)开头。 例如,当调用ClassLoader的getSystemResource()方法时,将使用java/lang/Object.class作为资源名称。 Class类中的资源查找方法可以指定绝对和相对资源名称。绝对资源名称以斜线开头,而相对资源名称不用。 当使用绝对名称时,Class类中的方法会删除前导斜线并委派给加载Class对象的类加载器来查找资源。 以下调用 Test.class.getResource("/resources/test.config"); 会被转换成 Test.class.getClassLoader().getResource("resources/test.config"); 当使用相对名称时,Class类中的方法预先添加了包名称,在使用斜线后跟斜线替换包名中的点,然后再委托加载Class对象的类加载器来查找资源。 假设测试类在com.jdojo.test包中,以下调用: Test.class.getResource("resources/test.config"); 会被转换成 Test.class.getClassLoader().getResource("com/jdojo/test/resources/test.config");

2. 在JDK 9 中访问资源

在JDK 9之前,可以从类路径上的任何JAR访问资源。 在JDK 9中,类和资源封装在模块中。 在第一次尝试中,JDK 9设计人员强制执行模块封装规则,模块中的资源必须对该模块是私有的,因此它们只能在该模块内的代码中访问。 虽然这个规则在理论上看起来很好,但是对于跨模块共享资源的框架和加载的类文件作为来自其他模块的资源,就会带来问题。 为了有限地访问模块中的资源,做了一些妥协,但是仍然强制执行模块的封装。 JDK 9包含三类资源查找方法: java.lang.Class java.lang.ClassLoader java.lang.Module Class和ClassLoader类没新增任何新的方法。 Module类包含一个getResourceAsStream(String name)方法,如果找到该资源,返回一个InputStream;否则返回null。

(三):模块化

模块化特性是Java 9 最大的一个特性,Java 9起初的代号就叫Jigsaw,后来被更改为Modularity,Modularity提供了类似于OSGI框架的功能,模块之间存在相互的依赖关系,可以导出一个公共的API,并且隐藏实现的细节,Java提供该功能的主要的动机在于,减少内存的开销,我们大家都知道,在JVM启动的时候,至少会有30~60MB的内存加载,主要原因是JVM需要加载rt.jar,不管其中的类是否被classloader加载,第一步整个jar都会被JVM加载到内存当中去,模块化可以根据模块的需要加载程序运行需要的class,那么JVM是如何知道需要加载那些class的呢?这就是在Java 9 中引入的一个新的文件module.java我们大致来看一下一个例子(module-info.java)

1234

module com.baeldung.java9.modules.car { requires com.baeldung.java9.modules.engines; exports com.baeldung.java9.modules.car.handling; }

Java 平台级模块系统

Java 9的定义功能是一套全新的模块系统。当代码库越来越大,创建复杂,盘根错节的“意大利面条式代码”的几率呈指数级的增长。这时候就得面对两个基础的问题: 很难真正地对代码进行封装, 而系统并没有对不同部分(也就是 JAR 文件)之间的依赖关系有个明确的概念。每一个公共类都可以被类路径之下任何其它的公共类所访问到, 这样就会导致无意中使用了并不想被公开访问的 API。此外,类路径本身也存在问题: 你怎么知晓所有需要的 JAR 都已经有了, 或者是不是会有重复的项呢? 模块系统把这俩个问题都给解决了。 模块化的 JAR 文件都包含一个额外的模块描述器。在这个模块描述器中, 对其它模块的依赖是通过 “requires” 来表示的。另外, “exports” 语句控制着哪些包是可以被其它模块访问到的。所有不被导出的包默认都封装在模块的里面。如下是一个模块描述器的示例,存在于 “module-info.java” 文件中:

12345

module blog { exports com.pluralsight.blog; requires cms;}

我们可以如下展示模块:

请注意,两个模块都包含封装的包,因为它们没有被导出(使用橙色盾牌可视化)。 没有人会偶然地使用来自这些包中的类。Java 平台本身也使用自己的模块系统进行了模块化。通过封装 JDK 的内部类,平台更安全,持续改进也更容易。当启动一个模块化应用时, JVM 会验证是否所有的模块都能使用,这基于 requires 语句——比脆弱的类路径迈进了一大步。模块允许你更好地强制结构化封装你的应用并明确依赖。

(四):JShel,交互式 Java REPL

许多语言已经具有交互式编程环境,Java 现在加入了这个俱乐部。您可以从控制台启动 jshell ,并直接启动输入和执行 Java 代码。 jshell 的即时反馈使它成为探索 API 和尝试语言特性的好工具。

测试一个 Java 正则表达式是一个很好的说明 jshell 如何使您的生活更轻松的例子。 交互式 shell 还可以提供良好的教学环境以及提高生产力,您可以在此了解更多信息。在教人们如何编写 Java 的过程中,不再需要解释 “public static void main(String [] args)” 这句废话。

JShell详解

JShell项目是第一个官方的Java REPL (Read-Eval-Print-Loop的缩写,即交互式编程环境),是一种命令行工具。它允许你无需使用类或者方法包装来执行Java语句。它与Python的解释器类似,或其它本地支持REPL的JVM语言,如Scala和Groovy。在Java 9新特性中,这绝对是更有趣的特性之一。下面让我们看看JShell一些最有趣的特性。

1 分号对于纯语句是可选的

实际上,在发起的一个关于未来Java特性的调查中,该特性是受多数人认可的。当然分号仍被保留了下来,无论是作为终结符还是分隔符。REPL允许一次性键入纯表达式和语句,因此分号对于JShell终端用例是可选的。

2 没有受检异常

如果你一直担心受检异常会毁掉你的REPL经历——无需再担心,JShell在后台为你隐藏好了。在下面的例子中,本应当强迫我们捕获一个IOException,却没有出现。下面的例子是我们在读取和打印一个文件,不需要处理IOException。

有一种情况的确会有受检异常弹出,就是当我们尝试运行一个线程,并在里面使用了 Thread.sleep() 语句。由于这是一个整体的方法而非单独的纯语句,它必须是完全有效的Java语句:

3 Java表达式

JShell终端还可以自己计算Java表达式。字符串连接、方法回调、算法,诸如此类。基本上,任何你可以包装在 System.out.println(/ expression here /) 里的都可以计算。正如你可能已经知道到的其它计算方式,它会立即将结果赋给自己的一个变量并打印出来。

4 向前引用

JShell给向前引用提供了很棒的支持,所以你在定义方法时可以引用其他方法或变量,且这些方法或变量仅会在一段时间后被定义。这是AdoptOpenJDK提供的REPL指南中的一个例子:

5 REPL网络

使用JShell时,我们不会受限于机器和网络访问,这带来了一些有趣的机会。例如,想想把它当做一个终端来与服务器交流,远程连接到服务器并且从外面控制一些参数。另一个选择是查询数据库,这里真的是有无限可能。

(五):集合工厂方法

通常,您希望在代码中创建一个集合(例如,List 或 Set ),并直接用一些元素填充它。 实例化集合,几个 “add” 调用,使得代码重复。 Java 9,添加了几种集合工厂方法:

12

Set<Integer> ints = Set.of(1, 2, 3);List<String> strings = List.of("first", "second");

除了更短和更好阅读之外,这些方法也可以避免您选择特定的集合实现。 事实上,从工厂方法返回已放入数个元素的集合实现是高度优化的。这是可能的,因为它们是不可变的:在创建后,继续添加元素到这些集合会导致 “UnsupportedOperationException” 。

(六):改进的 Stream API

长期以来,Stream API 都是 Java 标准库最好的改进之一。通过这套 API 可以在集合上建立用于转换的申明管道。在 Java 9 中它会变得更好。Stream 接口中添加了 4 个新的方法:dropWhile, takeWhile, ofNullable。还有个 iterate 方法的新重载方法,可以让你提供一个 Predicate (判断条件)来指定什么时候结束迭代:

1

IntStream.iterate(1, i -> i < 100, i -> i + 1).forEach(System.out::println);

第二个参数是一个 Lambda,它会在当前 IntStream 中的元素到达 100 的时候返回 true。因此这个简单的示例是向控制台打印 1 到 99。 除了对 Stream 本身的扩展,Optional 和 Stream 之间的结合也得到了改进。现在可以通过 Optional 的新方法 stram将一个 Optional 对象转换为一个(可能是空的) Stream 对象:

1

Stream<Integer> s = Optional.of(1).stream();

在组合复杂的 Stream 管道时,将 Optional 转换为 Stream 非常有用。

(七):多版本兼容JAR

多版本兼容JAR这个特性对于库的维护者而言是个特别好的消息。当一个新版本的 Java 出现的时候,你的库用户要花费数年时间才会切换到这个新的版本。这就意味着库得去向后兼容你想要支持的最老的 Java 版本 (许多情况下就是 Java 6 或者 7)。这实际上意味着未来的很长一段时间,你都不能在库中运用 Java 9 所提供的新特性。幸运的是,多版本兼容 JAR 功能能让你创建仅在特定版本的 Java 环境中运行库程序时选择使用的 class 版本:

123456789

multirelease.jar├── META-INF│ └── versions│ └── 9│ └── multirelease│ └── Helper.class├── multirelease ├── Helper.class └── Main.class

在上述场景中, multirelease.jar 可以在 Java 9 中使用, 不过 Helper 这个类使用的不是顶层的 multirelease.Helper 这个 class, 而是处在“META-INF/versions/9”下面的这个。这是特别为 Java 9 准备的 class 版本,可以运用 Java 9 所提供的特性和库。同时,在早期的 Java 诸版本中使用这个 JAR 也是能运行的,因为较老版本的 Java 只会看到顶层的这个 Helper 类。

(八):私有接口方法

Java 8 为我们带来了接口的默认方法。 接口现在也可以包含行为,而不仅仅是方法签名。 但是,如果在接口上有几个默认方法,代码几乎相同,会发生什么情况? 通常,您将重构这些方法,调用一个可复用的私有方法。 但默认方法不能是私有的。 将复用代码创建为一个默认方法不是一个解决方案,因为该辅助方法会成为公共API的一部分。 使用 Java 9,您可以向接口添加私有辅助方法来解决此问题:

1234567

public interface MyInterface { void normalInterfaceMethod(); default void interfaceMethodWithDefault() { init(); } default void anotherDefaultMethod() { init(); } // This method is not part of the public API exposed by MyInterface private void init() { System.out.println("Initializing"); }}

如果您使用默认方法开发 API ,那么私有接口方法可能有助于构建其实现。

(九):HTTP/2

Java 9 中有新的方式来处理 HTTP 调用。这个迟到的特性用于代替老旧的 HttpURLConnection API,并提供对 WebSocket 和 HTTP/2 的支持。注意:新的 HttpClient API 在 Java 9 中以所谓的孵化器模块交付。也就是说,这套 API 不能保证 100% 完成。不过你可以在 Java 9 中开始使用这套 API:

12345678

HttpClient client = HttpClient.newHttpClient();HttpRequest req =HttpRequest.newBuilder(URI.create("http://www.google.com")) .header("User-Agent","Java") .GET() .build();HttpResponse<String> resp = client.send(req, HttpResponse.BodyHandler.asString());HttpResponse<String> resp = client.send(req, HttpResponse.BodyHandler.asString());

除了这个简单的请求/响应模型之外,HttpClient 还提供了新的 API 来处理 HTTP/2 的特性,比如流和服务端推送。


JDK 10新特性

JDK10 包含 12 个JEP (改善提议):

  • 【286】局部变量类型推断 :对于开发者来说,这是 JDK10 唯一的真正特性。它向 Java 中引入在其他语言中很常见的 var ,比如 JavaScript 。只要编译器可以推断此种类型,你不再需要专门声明一个局部变量的类型。一个简单的例子是: var x = new ArrayList<String>(); 这就消除了我们之前必须执行的 ArrayList<String> 类型定义的重复。我鼓励你们去读 JEP ,因为上面有一些关于这个句法是否能用的规则。 有趣的是,需要注意 var 不能成为一个关键字,而是一个保留字。这意味着你仍然可以使用 var 作为一个变量,方法或包名,但是现在(尽管我确定你绝不会)你不能再有一个类被调用。
  • [310]应用类数据共享(CDS) :CDS 在 JDK5 时被引进以改善 JVM 启动的表现,同时减少当多个虚拟机在同一个物理或虚拟的机器上运行时的资源占用。 JDK10 将扩展 CDS 到允许内部系统的类加载器、内部平台的类加载器和自定义类加载器来加载获得的类。之前,CDS 的使用仅仅限制在了 bootstrap 的类加载器。
  • [314]额外的 Unicode 语言标签扩展:这将改善 java.util.Locale 类和相关的 API 以实现额外 BCP 47 语言标签的 Unicode 扩展。尤其是,货币类型,一周的第一天,区域覆盖和时区等标签现在将被支持。
  • [322]基于时间的版本控制:正如我在之前的博客中所讨论的,我们的 JDK 版本字符串格式几乎与 JDK 版本一样多。有幸的是,这是最后需要使用到的,我们可以坚持用它。这种格式使用起来很像 JDK9 中介绍的提供一个更加语义的形式。有一件困扰我的事是包含了一个 INTERIM 元素,正如 JEP 提议中所说,“永远是0”。好吧,如果永远是0,那它有什么意义呢?他们说这是为未来使用做保留,但我仍不是很赞同。我认为,这有些冗余繁杂。 这也消除了在 JDK9 中有过的相当奇怪的情形。第一次更新是 JDK 9.0.1 , 非常符合逻辑。第二次更新是 JDK 9.0.4 ,不合逻辑。原因是,在 JDK9 的版本计数模式下,需要留下空白以便应急或不在预期安排的更新使用。但既然没有更新是必须的,为什么不简单称之为 JDK 9.0.2 呢?
  • [319]根证书:在 JDK 中将提供一套默认的 CA 根证书。关键的安全部件,如 TLS ,在 OpenJDK 构建中将默认有效。这是 Oracle 正在努力确保 OpenJDK 二进制和 Oracle JDK 二进制功能上一样的工作的一部分,是一项有用的补充内容。
  • [307] 并行全垃圾回收器 G1 : G1 是设计来作为一种低延时的垃圾回收器(但是如果它跟不上旧的堆碎片产生的提升速率的话,将仍然采用完整压缩集合)。在 JDK9 之前,默认的收集器是并行,吞吐,收集器。为了减少在使用默认的收集器的应用性能配置文件的差异,G1 现在有一个并行完整收集机制。
  • [313]移除 Native-Header 自动生成工具:Java9 开始了一些对 JDK 的家务管理,这项特性是对它的延续。当编译 JNI 代码时,已不再需要单独的工具来生成头文件,因为这可以通过 javac 完成。在未来的某一时刻,JNI 将会被 Panama 项目的结果取代,但是何时发生还不清楚。
  • [304]垃圾回收器接口: 这不是让开发者用来控制垃圾回收的接口;而是一个在 JVM 源代码中的允许另外的垃圾回收器快速方便的集成的接口。
  • [312]线程-局部变量管控:这是在 JVM 内部相当低级别的更改,现在将允许在不运行全局虚拟机安全点的情况下实现线程回调。这将使得停止单个线程变得可能和便宜,而不是只能启用或停止所有线程。
  • [316]在备用存储装置上的堆分配:硬件技术在持续进化,现在可以使用与传统 DRAM 具有相同接口和类似性能特点的非易失性 RAM 。这项 JEP 将使得 JVM 能够使用适用于不同类型的存储机制的堆。
  • [317] 试验性的基于 Java 的 JIT 编译器:最近宣布的 Metropolis 项目,提议用 Java 重写大部分 JVM 。乍一想,觉得很奇怪。如果 JVM 是用 Java 编写的,那么是否需要一个 JVM 来运行 JVM ? 相应的,这导致了一个很好的镜像类比。 现实情况是,使用 Java 编写 JVM 并不意味着必须将其编译为字节码,你可以使用 AOT 编译,然后在运行时编译代码以提高性能。 这项 JEP 将 Graal 编译器研究项目引入到 JDK 中。并给将 Metropolis 项目成为现实,使 JVM 性能与当前 C++ 所写版本匹敌(或有幸超越)提供基础。
  • [296]: 合并 JDK 多个代码仓库到一个单独的储存库中:在 JDK9 中,有 8 个仓库: root、corba、hotspot、jaxp、jaxws、jdk、langtools 和 nashorn 。在 JDK10 中这些将被合并为一个,使得跨相互依赖的变更集的存储库运行 atomic commit (原子提交)成为可能。

新 API

有 73 项新增内容添加到了标准类库中。

  • java.awt.Toolkit int getMenuShortcutKeyMaskEx(): 确定哪个扩展修饰符键是菜单快捷键的适当加速键。
  • java.awt.geom.Path2D: void trimToSize(): 将此 Path2D 实例的容量计算到它当前的大小。应用可使用此操作将路径的存储空间最小化。这个方法也被添加到 Path2D.Double 和 Path2D.Float 类。
  • java.io.ByteArrayOutputStream: String toString(Charset): 重载 toString(),通过使用指定的字符集解码字节,将缓冲区的内容转换为字符串。
  • java.io.PrintStream: lang.io.PrintWriter: 这两个类都有三个新的构造函数,它们需要额外的 Charset 参数。
  • java.io.Reader: long transferTo(Writer): 从这个 Reader 中读取所有字符,并按照所读的顺序将字符写入给定的 Writer 。
  • java.lang.Runtime.Version: 有四种新方法返回新(JEP 322)版本字符串字段的整数值: feature()、interim()、patch() 和 update() 。
  • java.lang.StackWalker.StackFrame: String getDescriptor(): 按照 JVM 标准返回此堆栈帧所代表的方法的描述符。 String getMethodType():返回此堆栈帧所代表的方法类型,描述参数类型和返回值类型。
  • java.lang.invoke.MethodType: Class<?> lastParameterType():返回这个方法类型的最后一个参数类型。如果这个方法类型没有参数,则返回空类型作为岗哨值(Sentinel Value)。
  • java.lang.management.RuntimeMXBean: long getPid(): R 返回正在运行的 JVM 的进程 ID 。
  • java.lang.management.ThreadMXBean: ThreadInfo[] dumpAllThreads(boolean, boolean, int): 返回所有活动线程的线程信息,其中有指定的最大元素数量和同步信息的堆栈跟踪。 ThreadInfo[] getThreadInfo(long[], boolean, boolean, int): 返回每个线程的线程信息,这些线程的标识位于输入数组中,其中有指定的最大元素数量和同步信息的堆栈跟踪。
  • java.lang.reflect.MalformedParameterizedTypeException: 添加了一个新的构造函数,它以字符串的形式作为参数来获取详细信息。
  • java.net.URLDecoder: java.net.URLEncoder: 这两个类都有新的重载的解码和编码方法,将 charset 作为附加参数。
  • java.nio.channels.Channels: 两个新的静态重载方法,newReader(ReadByteChannel, Charset)和newWriter(WriteByteChannel, Charset) ,允许使用字符集。
  • java.nio.file.FileStore: long getBlockSize(): 返回 file 中每个 block 的比特数。
  • java.time.chrono: 这个包中有三个类,HijrahEra、MiinguoEra 和 ThaiBuddhistEra 中都增加了这个方法。 String getDisplayName(TextStyle, Locale): 这将返回用于标识事件的文本名称,适用于向用户演示。
  • java.time.format.DateTimeFormatter: localizedBy(Locale): 返回一个含有本地化后的 locale、calendar、region、decimal 样式和时区的 formatter 副本,来取代该 formatter 中的值。
  • java.util: DoubleSummaryStatistics、IntSummaryStatistics 和 LongSummaryStatistics 都将有一个新的构造方法,新的构造方法需要 4 个数值类型值。该构造方法创建一个含有计数、最小值、最大值和总计值的实例。
  • java.util.List: java.util.Map: java.util.Set: 这三个包下的所有接口都新增一个新的静态方法 copyOf(Collection) 。这个方法会返回一个不可修改的 List、Map 或者 Set ,其中按迭代器的顺序包含了给出的 Collection 中的元素。
  • java.util.Optional: java.util.OptionalDouble: java.util.OptionalInt: java.util.OptionalLong: 这四个类都新增一个新的方法 orElseThrow() ,功能上与 get() 基本一样。换言之,如果 Optional 中有值则返回,否则抛出一个 NoSuchElementException 异常。
  • java.util.Formatter: java.util.Scanner: 这两个类新增三个新的构造函数,除了其他参数之外,所有这些构造函数都需要字符集作为参数。

其它翻译版本

  • java.util.Properties: 这有一个新的构造函数,它接受一个 int 参数。这将创建一个没有默认值的空属性列表,并且指定初始大小以容纳指定的元素数量,而无需动态调整大小。还有一个新的重载的 replace 方法,接受三个 Object 参数并返回一个布尔值。只有在当前映射到指定值时,才会替换指定键的条目。
  • java.SplittableRandom: void nextBytes(byte[]): 用生成的伪随机字节填充一个用户提供的字节数组。
  • java.util.concurrent.FutureTask: 添加了 toString() 方法,该方法返回一个标识 FutureTask 的字符串,以及它的完成状态。在括号中,状态包含如下字符串中的一个,“Completed Normally” 、“Completed Exceptionally”、 “Cancelled” 或者 “Not completed”。
  • java.util.concurrent.locks.StampedLock: boolean isLockStamp(long): 返回一个标记戳表示是否持有一个锁。 boolean isOptimisticReadStamp(long): 返回一个标记戳代表是否成功的进行了乐观读(optimistic read)。 boolean isReadLockStamp(long): 返回一个标记戳表示是否持有一个非独占锁(即 read lock )。 boolean isWriteLockStamp(long): 返回一个标记戳表示是否持有一个独占锁(即 write lock )。
  • java.jar.JarEntry: String getRealName(): 返回这个 JarEntry 的真实名称。如果这个 JarEntry 是一个多版本 jar 文件的入口,它被配置为这样处理,这个方法返回的名字是 JarEntry 所代表的版本条目的入口,而不是 ZipEntry.getName() 返回的基本条目的路径名。如果 JarEntry 不代表一个多版本 jar 文件的版本化条目或者 jar 文件没有被配置为作为一个多版本 jar 文件进行处理,这个方法将返回与 ZipEntry.getName() 返回的相同名称。
  • java.util.jar.JarFile: Stream<JarEntry> versionedStream(): 返回 jar 文件中指定版本的入口对应 Stream 。与 JarEntry 的 getRealName 方法类似,这与多版本 jar 文件有关。
  • java.util.spi.LocaleNameProvider: getDisplayUnicodeExtensionKey(String, Locale): 为给定的 Unicode 扩展键返回一个本地化名称。 getDisplayUnicodeExtensionType(String, String, Locale): 为给定的 Unicode 扩展键返回一个本地化名称。
  • java.util.stream.Collectors: toUnmodifiableList(): toUnmodifiableSet(): toUnmodifiableMap(Function, Function): toUnmodifiableMap(Function, Function, BinaryOperator): 这四个新方法都返回 Collectors ,将输入元素聚集到适当的不可修改的集合中。
  • java.lang.model.SourceVersion: 现在有了一个字段,它代表了 JDK 10 的版本。
  • java.lang.model.util.TypeKindVisitor6: javax.lang.model.util.TypeKindVisitor9: (我必须承认,我从来没听说过这些类) R visitNoTypeAsModule(NoType, P): 访问一个 MODULE 的 pseudo-type 。我不确定为什么只有这两个类得到这个方法,因为还有 Visitor7 和 Visitor8 变量。
  • javax.remote.management.rmi.RMIConnectorServer: 这个类已经添加了两个字段: CREDENTIALS_FILTER_PATTERN 和 SERIAL_FILTER_PATTERN 。
  • javax.ButtonModel:看,Swing 还在更新! ButtonGroup getGroup(): 返回按钮所属的组。通常用于单选按钮,它们在组中是互斥的。
  • javax.plaf.basic.BasicMenuUI: Dimension getMinimumSize(JComponent): 返回指定组件适合观感的最小大小。

JVM 规范改动

这些改动相当小:

  • 4.6节:类文件格式(第99页)。在方法访问标志方面有小的改动。
  • 4.7节:模块属性(第169页)。如果模块不是 java.base ,则 JDK 10 不再允许设置 ACC_TRANSITIVE 或 ACC_STATIC_PHASE 。
  • 4.10节:类文件的校验(第252页)。dup2 指令已改变了 typesafe form 1 的定义,颠倒了 canSafleyPushList 一节中类型的顺序(你需要仔细查看才能发现它)。
  • 5.2节:Java 虚拟机启动(第350页)。该描述添加了在创建初始类或接口时可使用用户定义的类加载器( bootstrap 类加载器除外)。

对 Java 语言规范的更改

这里还有一些更改,但主要是为了支持局部变量类型推断。

  • 第3.8节:标识符(第23页)。在忽略了可忽略的字符之后,标识符的等价性现在被考虑了。这似乎是合乎逻辑的。 (第24页)一个新的 Token,TypeIdentifier,它支持对局部变量类型推断的新用法,而 var 的使用不是关键字,而是一个具有特殊含义的标识符,作为局部变量声明的类型。
  • 第4.10.5节:类型预测(第76页)。这是一个相当复杂的部分,它涉及到捕获变量、嵌套类以及如何使用局部变量类型推断。我建议你阅读规范中的这一部分,而不是试图解释它。
  • 第6.1节:声明(第134页)。一个反映使用 TypeIdentifier 来支持局部变量类型的推断的小改动。
  • 第6.5节:确定名字的含义(第153页,第158页和第159页)。根据类型标识符的使用而更改类类型。
  • 第6.5.4.1:简单的 PackageOrTypeNames(第160页)
  • 第6.5.4.2节:合规的 PackageOrTypeNames(第160页)。这两种方式都与使用 TypeIdentifier 有细微的变化。
  • 第7.5.3:单静态导入声明(第191页)。这改变了导入具有相同名称的静态类型的规则。除非类型是相同的,否则这将成为一个错误,在这种情况下,重复被忽略。
  • 第7.7.1:依赖(第198页)。如果你明确声明一个模块需要 java.base ,那在必要的关键字之后,你就不能再使用修饰符(例如静态)了。
  • 第8部分:正式参数(第244页)。接收者参数可能只出现在一个实例方法的 formalparameters 列表,或者是一个内部类的构造函数中,其中内部类没有在静态上下文中声明。
  • 第9.7.4节:注释可能出现的地方(第335页)。有一个与局部变量类型推断相关的变更。
  • 第14.4部分:局部变量声明语句(第433页)。实现局部变量类型推断所需的大量更改。
  • 第14节:增强的 for 语句(第455页)。这个结构已经更新,包括对局部变量类型推断的支持。
  • 第14.20.3节:try-with-resources(474页)。这个结构已经更新,包括对局部变量类型推断的支持。

最后,第 19 章有多处语法更新,反映了应更多使用 TypeIdentifier 类型标识符,而不仅仅是 Identifier 标识符,以支持局部变量类型推断。


JDK 11新特性

Java 11 JDK中已计划的新功能

目前来看,JDK 11已有九个已经确认的新功能,而且还有更多新功能仍在考虑之中。计划的新功能包括:

HTTP客户端(标准),这个功能于JDK 9中引入并在JDK 10中得到了更新,现在终于转正了。该API通过CompleteableFutures提供非阻塞请求和响应语义,可以联合使用以触发相应的动作。自从JDK 9和10中引入该功能后,JDK 11完全重写了该功能,现在其实现完全是异步的。RX Flow的概念也得到了实现,这样就无需为了支持HTTP/2而创造许多概念了。现在,在用户层请求发布者和响应发布者与底层套接字之间追踪数据流更容易了。这降低了复杂性,并最大程度上提高了HTTP/1和HTTP/2之间的重用的可能性。Epsilon垃圾回收器,被称为“no-op”回收器,它仅负责内存分配,却没有实现任何实际的内存回收机制。Epsilon回收器可以用于性能测试、内存压力测试和虚拟机接口。它还可以用于短生命周期的任务。lambda参数的局部变量语法,可以消除隐含类型表达式中正式参数定义的语法与局部变量定义语法的不一致。这样就能在隐含类型的lambda表达式中定义正式参数时使用var了。Java的类文件格式将被扩展,以支持新的常量池,CONSTANT_Dynamic。其目标是降低开发新形式的可实现类文件约束带来的成本和干扰。采用Curve25519和Curve448加密的密钥交换比现有的Diffie-Hellman椭圆曲线密钥交换方式更有效、更安全。根据IETF的资料,Curve25519和Curve448两种椭圆曲线采用常量时间的实现方式,以及不会发生异常的数乘实现,能更好地抵抗各种旁路攻击,包括时序攻击、缓存攻击等。该提案的目标是为密钥交换方法提供一个API和实现,同时开发一个平台无关、纯Java的的实现。由于该提案采用了复杂且精密的模算数,因此还是有风险的。飞行记录仪(Flight Recorder)将提供低开销的数据收集框架,用来调试Java应用程序和HotSpot JVM。飞行记录仪是Oracle的商业版JDK的功能,但在JDK 11中,其代码将移动到公开代码库中,这样所有人都能使用该功能了。Iclouded将作为API,以事件的形式产生或消耗数据,同时提供缓存机制、二进制数据工具,同时支持配置和事件过滤。该提案还提议为OS、HotSpot和JDK库提供事件。更新platform API以支持Unicode版本10.0,从而使Java跟上潮流。预计以下的类将支持:lang包中的Character和Stringawt.font包中的NumericShapertext包中的Bidi、BreakIterator和Normalizer实现ChaCha20和Poly1305加密算法。ChaCha20是种相对较新的流加密算法,能代替旧的、不安全的R4流加密。ChaCha20将与Poly1305认证算法配对使用。ChaCha20和ChaCha20-Poly1305加密实现将通过crypto.CipherSpi API于SunJCE(Java加密扩展)中提供。增强Java启动器,使之能够运行单一文件的Java源代码,使得应用程序可以直接从源代码运行。单文件程序常见于小型工具,或开发者初学Java时使用。而且,单一源代码文件有可能会编译成多个类文件,这会增加打包开销。由于这些原因,在运行程序之前进行编译,已成为了不必要的步骤。Java JDK 11仍在开发中的新功能

Java 11的创建者们还在考虑几个对JDK 11的变更或新功能的提案:

给Java添加raw字符串字面值。这样可以更容易地以人类可阅读的形式书写字符序列,而无需特殊的Java标记。这样也能更容易地将非Java语法的字符串提供给Java使用,还能支持多行字符串,而无需使用特殊的标记。扩展switch语句,使之能作为语句或表达式使用。这样还能改进switch处理null值的方式。这些改动可以简化编程,同时为switch支持模式匹配做准备。嵌套的访问控制,对应于Java当前的嵌套类型。嵌套可以让逻辑上属于同一代码实体但被编译到不同的类文件中的类互相访问对方的私有成员,而无需让编译器插入扩大访问权限的方法。JDK 11删除的功能

Java EE和CORBA模块从Java SE9就成了不推荐使用(deprecated),并计划在未来的版本中删除。这个未来版本就是JDK 11。

Java SE 6于2006年12越发布,它为Java EE平台提供了整套的Web服务技术栈:JAX-WS(Java API for XML-based Web Services),JAXB(Java Architecture for XML Binding),JAF(JavaBeans Activation Framework),以及Common Annotations for Java。这些年来,Java EE版本在不断进化,这给Java SE造成了许多麻烦,例如加入与Java SE无关的技术,以及同时维护两个Java版本的困难变得更大。由于独立的Java EE版本由第三方网站提供,Oracle说Java SE或JDK中已经没有必要提供Java EE了。

当然,一些依赖于JDK中的Java EE API及工具的应用程序将无法编译或运行。将JDK 6、7或8移植到新版本时将会产生二进制不兼容和源代码不兼容。Oracle说,受到这些影响的开发者可以部署相应的Java EE版本。

CORBA来自于二十世纪九十年代,Oracle说,现在用CORBA开发现代Java应用程序已经没有意义了,维护CORBA的成本已经超过了保留它带来的好处。

但是删除CORBA将使得那些依赖于JDK提供部分CORBA API的CORBA实现无法运行。目前还没有第三方CORBA版本,也不确定是否会有第三方愿意接手CORBA API的维护工作。

JavaFX已经被移除,因此已经与Java JDK每年两次的更新无关。

想想12会有那些新特性,欢迎在下方留言!!!

原文发布于微信公众号 - Java帮帮(javahelp)

原文发表时间:2018-08-31

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏battcn

一起学设计模式 - 命令模式

命令模式:对命令的封装,把发送命令和执行命令的责任分割开,分别委派给不同的对象,每一个命令都是一个操作,允许请求方与接收方独立开来,使之请求方不必清楚接收方的接...

12120
来自专栏听雨堂

VB下中文URL编码问题的解决

        因为编码涉及的内容既多且烦,特别是vb的编码,又有诸多限制,所以在解决URL中文编码的时候走了很久的弯路。 问题:         我的VB...

67660
来自专栏C/C++基础

腾讯2016春季校园实习招聘技术岗初试(一面)问题汇总(CC++后台)

2016.4.11日广州参加了腾讯的CC++后台技术一面,安全技术类的面试。面试官人很温和,经历了大概70分钟的问答,特将遇到的面试问题汇总如下,自己总结学习,...

9310
来自专栏北京马哥教育

编写Linux Shell脚本的最佳实践

来自:Myths的个人博客 作者:myths 链接:https://blog.mythsman.com/2017/07/23/1/(点击尾部阅读原文前往) 前言...

42590
来自专栏Golang语言社区

Go语言并发编程总结

Golang :不要通过共享内存来通信,而应该通过通信来共享内存。这句风靡在Go社区的话,说的就是 goroutine中的 channel ....... 他在...

31770
来自专栏眯眯眼猫头鹰的小树杈

猫头鹰的深夜翻译:Volatile的原子性, 可见性和有序性

为什么要额外写一篇文章来研究volatile呢?是因为这可能是并发中最令人困惑以及最被误解的结构。我看过不少解释volatile的博客,但是大多数要么不完整,要...

17350
来自专栏Golang语言社区

Go语言并发编程总结

Golang :不要通过共享内存来通信,而应该通过通信来共享内存。这句风靡在Go社区的话,说的就是 goroutine中的 channel ....... 他在...

36590
来自专栏腾讯移动品质中心TMQ的专栏

内存泄漏漫谈

对于C/C++来说,内存泄漏问题一直是个很让人头痛的问题,因为对于没有GC的语言,内存泄漏的概率要比有GC的语言大得多,同时,一旦发生问题,也严重的多,而且,内...

33770
来自专栏JavaEdge

JSP必备知识点servlet VS CGI如何实现 servlet 单线程模式servlet 页面间对象传递的方法有几种jsp VS servlet<jsp:include page=”includ

37360
来自专栏java一日一条

Java线程面试题 Top 50

不管你是新程序员还是老手,你一定在面试中遇到过有关线程的问题。Java语言一个重要的特点就是内置了对并发的支持,让Java大受企业和程序员的欢迎。大多数待遇丰厚...

13820

扫码关注云+社区

领取腾讯云代金券