JDK 11新特性 – 新功能和增强功能
以下注释描述了JavaSE11和JDK11中的一些增强功能。这些描述可能包含指向更详细描述增强功能的其他文档的链接。此处描述的API是随Oracle JDK提供的API。它包括JavaSE11平台的完整实现和其他JavaAPI,以支持Java应用程序的开发,调试和监视。有关JavaSE 11和JDK11中重要增强功能和新功能的另一个信息来源是JavaSE11(18.9)(JSR384)平台规范,它记录了JavaSE10和JavaSE11之间对规范所做的更改。文档包括那些新功能和增强功能的说明,这些功能和增强功能也是规范的变更。以下描述还可能标识迁移到JDK11时可能遇到的潜在兼容性问题。
核心库/java.lang中
➜JEP327 Unicode10 升级现有平台API以支持Unicode标准版本10.0(JEP 327:Unicode 10)。JDK 11版本包括对Unicode10.0.0的支持。 自从支持Unicode 8.0.0的JDK10发布以来,JDK 11结合了Unicode 9.0.0和10.0.0版本,包括:16018个新字符、18个新区块、10个新脚本。
16018个新字符包含以下重要内容:
- 新4K电视标准的19个符号
- 比特币的标志
- 128个表情符号字符
10个新脚本: - Adlam
- Bhaiksuki
- 童话
- 纽瓦
- 奥沙
- 西夏文
- MasaramGondi
- 女书
- Soyombo
- Zanabazar广场
18个新块,包括10个用于上面列出的新脚本的块和8个用于以下现有脚本的块: - CyrillicExtended-C
- 蒙古语补编
- 表意符号和标点符号
- 西夏组件
- Glagolitic补充剂
- 叙利亚补充
- 假名扩展-A
- CJKExtension F.
核心库/ java.net
➜JEP321 HTTP客户端(标准)
通过JEP 110标准化JDK 9中引入的孵化HTTP客户端API,并在JDK 10(JEP 321)中进行更新。
HTTP客户端已在Java 11中标准化。作为此工作的一部分,已删除位于jdk.incubator.http包中的以前孵化的API。 至少,需要更新使用jdk.incubator.http包中的类型的代码,以从标准包名称java.net.http导入HTTP类型。
核心库/ java.util中:collections
➜新的Collection.toArray(IntFunction)默认方法
在java.util.Collection接口中添加了一个新的默认方法toArray(IntFunction)。此方法允许将集合的元素传输到新创建的所需运行时类型的数组。
新方法是现有toArray(T [])方法的重载,该方法将数组实例作为参数。添加重载方法会导致次要源不兼容。以前,形式为coll.toArray(null)的代码将始终解析为现有的toArray方法。使用新的重载方法,此代码现在不明确,将导致编译时错误。 (这只是源不兼容。现有的二进制文件不受影响。)应该更改模糊代码以将null转换为所需的数组类型,例如toArray((Object [])null)或其他一些数组类型。请注意,将null传递给toArray方法指定为抛出NullPointerException。
核心库/ java.util中:I18N
➜将区域设置数据更新为Unicode CLDR v33
基于Unicode Consortium的CLDR(公共区域设置数据注册表)的区域设置数据已针对JDK 11进行了更新。补充平面中的本地化数字(例如,印度Chakma脚本中的数字)将替换为ASCII数字,直到JDK-8204092被解析。 缅甸语区域的中短时间模式尚未升级。 解析JDK-8209175后,将升级这些模式。
有关CLDR版本33的更多详细信息,请参阅http://cldr.unicode.org/index/downloads/cldr-33。
hotspot/编译
➜Lazy Allocation of Compiler Threads
添加了新的命令行标志-XX:+UseDynamicNumberOfCompilerThreads以动态控制编译器线程。 在分层编译模式(默认情况下处于启用状态)下,无论可用内存和编译请求数如何,VM都会在具有许多CPU的系统上启动大量编译器线程。 因为线程即使在空闲时也消耗内存(几乎所有时间都是如此),这导致资源的低效使用。
为解决此问题,已将实现更改为在启动期间仅启动每种类型的一个编译器线程,并动态处理其他线程的启动和关闭。 它由新的命令行标志控制,默认情况下处于打开状态:
-XX:+ UseDynamicNumberOfCompilerThreads
hotspot/ GC
➜JEP333 ZGC可扩展的低延迟垃圾收集器(实验性)
Z垃圾收集器,也称为ZGC,是一个可扩展的低延迟垃圾收集器(JEP 333)。它旨在实现以下目标:
- 暂停时间不超过10毫秒
- 暂停时间不会随堆或实时设置大小而增加
- 处理大小从几百兆到几千兆字节不等的堆
ZGC的核心是并发垃圾收集器,这意味着在Java线程继续执行时,所有繁重的工作(标记,压缩,引用处理,字符串表清理等)都已完成。这极大地限制了垃圾收集对应用程序响应时间的负面影响。
ZGC作为实验性功能包含在内。要启用它,因此需要将-XX:+ UnlockExperimentalVMOptions选项与-XX:+ UseZGC选项结合使用。
ZGC的这个实验版具有以下限制:
- 它仅适用于Linux / x64。
- 不支持使用压缩的oops和/或压缩的类点。默认情况下禁用-XX:+UseCompressedOops和-XX:+UseCompressedClassPointers选项。启用它们将不起作用。
- 不支持类卸载。默认情况下禁用-XX:+ ClassUnloading和-XX:+ ClassUnloadingWithConcurrentMark选项。启用它们将不起作用。
- 不支持将ZGC与Graal结合使用。
hotspot/ GC
➜JEP318 Epsilon,No-Op垃圾收集器
Epsilon GC是新的实验性无操作垃圾收集器。 Epsilon GC仅处理内存分配,并且不实现任何内存回收机制。 它对性能测试非常有用,可以与其他GC的成本/收益进行对比。 它可用于在测试中方便地断言内存占用和内存压力。在极端情况下,它可能对非常短暂的作业很有用,其中内存回收将在JVM终止时发生,或者在低垃圾应用程序中获得最后一次延迟改进。请参阅JEP 318中有关其使用和权衡的更多讨论。
hotspot/ JVMTI
➜JEP331Low-Overhead Heap Profiling
提供一种低开销的Java堆分配采样方法,可通过JVMTI(JEP 331)访问。
它旨在实现以下目标:
- 低开销足以在默认情况下持续启用
- 可通过定义明确的编程接口(JVMTI)访问
- 可以对所有分配进行采样(即,不限于在一个特定堆区域中的分配或以特定方式分配的分配)
- 可以以独立于实现的方式定义(即,不依赖于任何特定的GC算法或VM实现)
- 可以提供有关实时和死Java对象的信息
hotspot/runtime
➜JEP181 Nest-Based Access Control(基于嵌套的访问控制)
介绍嵌套,一种访问控制上下文,与Java编程语言中嵌套类型的现有概念一致(JEP-181:基于嵌套的访问控制)。
在Java SE 11中,Java虚拟机支持将类和接口安排到新的访问控制上下文中,称为嵌套。嵌套允许类和接口在逻辑上属于同一代码实体,但是被编译为不同的类文件,以访问彼此的私有成员,而无需编译器插入可访问性扩展桥接方法。嵌套是Java SE平台的低级机制; Java编程语言的访问控制规则没有变化。通过生成新的类文件属性(将顶级类(或接口)及其所有嵌套类和接口放在同一个嵌套中),javac编译器已经更新为在编译Java源代码中的嵌套类和接口时使用嵌套。在检查私有构造函数,方法或字段的可访问性时,Java虚拟机已更新为使用这些属性,包括通过核心反射和java.lang.invoke.MethodHandles.LookupAPI。嵌套中的成员资格通过java.lang.Class的新getNestHost和getNestMembers方法公开。
由于嵌套成员资格记录在顶级类或接口(嵌套主机)的类文件中,因此该类文件必须在运行时存在,以允许执行访问控制检查。这通常不是问题,因为通常直接使用顶级类或接口。在某些顶级类或接口仅作为嵌套类或接口的持有者并且未使用的代码中,打包工具可能已经从库或应用程序的分发中删除了该类文件。使用基于嵌套的访问控制,如果任何嵌套类或接口需要访问彼此的私有成员,则不再可能忽略顶级类或接口 – 将抛出NoClassDefFoundError或ClassNotFoundException。
security-libs
➜JEP324 Key Agreement with Curve25519 andCurve448(Curve25519和Curve448的密钥协议)
JEP 324使用如RFC 7748中所述的Curve25519和Curve448添加了新密钥协商方案的实现。此实现可用作Java加密体系结构服务,但尚未合并到新的TLS 1.3实现中。
security-libs/javax.crypto
➜(Added Brainpool EC Support (RFC 5639))添加了Brainpool EC支持(RFC 5639)
SunEC提供商已得到增强,可支持RFC5639,椭圆曲线密码术(ECC)Brainpool标准曲线和曲线生成中定义的4个额外Brainpool曲线。 可以使用标准名称为brainpoolP256r1,brainpoolP320r1,brainpoolP384r1和brainpoolP512r1的java.security.spec.ECGenParameterSpec对象创建相应的EC域参数。请注意,SunJSSE提供程序尚未得到增强,无法支持这些brainpool curves(脑池曲线)。
security-libs/javax.crypto
➜JEP329 ChaCha20和Poly1305加密算法
实现RFC 7539中指定的ChaCha20和ChaCha20-Poly1305密码.ChaCha20是一种新的流密码,可以替代旧的,不安全的RC4流密码。
那些希望获得ChaCha20流密码实例的人可以使用算法字符串“ChaCha20”和Cipher.getInstance方法。 那些希望在AEAD模式下使用ChaCha20和Poly1305验证器的人可以使用算法字符串“ChaCha20-Poly1305”。 有关更多详细信息,请参阅“Java安全标准算法名称”文档。
security-libs/javax.crypto
➜增强的KeyStore机制
引入了一个名为jceks.key.serialFilter的新安全属性。如果配置了此过滤器,则JCEKS KeyStore会在对SecretKeyEntry中存储的加密Key对象进行反序列化时使用它。 如果未配置或过滤结果为UNDECIDED(例如,没有模式匹配),则查询jdk.serialFilter配置的过滤器。如果还提供了系统属性jceks.key.serialFilter,它将取代此处定义的安全属性值。过滤器模式使用与jdk.serialFilter相同的格式。 默认模式允许java.lang.Enum,java.security.KeyRepjava.security.KeyRep $ Type和javax.crypto.spec.SecretKeySpec但拒绝所有其他模式。存储未序列化为上述类型的SecretKey的客户必须修改过滤器以使密钥可提取。
security-libs/javax.crypto
➜RSASSA-PSS签名支持已添加到SunMSCAPI
RSASSA-PSS签名算法支持已添加到SunMSCAPI提供程序中。
security-libs/javax.net.ssl
➜JEP332传输层安全性(TLS)1.3
JDK 11版本包括传输层安全性(TLS)1.3规范(RFC 8446)的实现。有关更多详细信息(包括支持的功能列表),请参阅Java安全套接字扩展(JSSE)参考指南文档和JEP 332。
对于TLS 1.3,定义了以下新标准算法名称:
- TLS协议版本名称:TLSv1.3
- SSLContext算法名称:TLSv1.3
- TLS 1.3的TLS密码套件名称:TLS_AES_128_GCM_SHA256,TLS_AES_256_GCM_SHA384
4.用于X509KeyManager的keyType:RSASSA-PSS
5.用于X509TrustManager的authType:RSASSA-PSS
为TLS 1.3添加了一个新的安全属性jdk.tls.keyLimits。当处理了特定算法的指定数据量时,触发握手后密钥和IV更新以导出新密钥。添加了一个新的系统属性jdk.tls.server.protocols,用于在SunJSSE提供程序的服务器端配置默认启用的协议套件。请注意,KRB5密码套件实现已从JDK中删除,因为它们不再被认为是安全的。
请注意,TLS 1.3与以前的版本不直接兼容。尽管可以使用向后兼容模式实现TLS 1.3,但在升级到TLS 1.3时仍需要考虑几个兼容性风险: - TLS 1.3使用半关闭策略,而TLS 1.2和先前版本使用双工关闭策略。对于依赖于双工关闭策略的应用程序,升级到TLS1.3时可能存在兼容性问题。
2.signature_algorithms_cert扩展要求使用预定义的签名算法进行证书身份验证。但是,实际上,应用程序可能会使用不受支持的签名算法。 - TLS 1.3不支持DSA签名算法。如果服务器配置为仅使用DSA证书,则无法升级到TLS 1.3。
- TLS 1.3支持的密码套件与TLS 1.2和早期版本不同。如果应用程序硬编码不再受支持的密码套件,则可能无法在不修改应用程序代码的情况下使用TLS 1.3。
- TLS 1.3会话恢复和密钥更新行为与TLS 1.2和先前版本不同。兼容性影响应该是最小的,但如果应用程序依赖于TLS协议的握手细节,则可能存在风险。
如果需要,可以使用系统属性jdk.tls.client.protocols和jdk.tls.server.protocols在SunJSSE提供程序中相应地配置默认启用的协议。
specification/language
➜JEP323:Lambda参数的本地变量语法
现在可以在声明lambda表达式的形式参数时使用保留类型名称var([JEP 323](http://openjdk.java.net/jeps/323))。这建立在Java SE 10中,在声明局部变量时使用var的能力。将var用于lambda表达式的形式参数会导致推断参数的类型,使用与var和explicit类型都不存在时相同的规则。 自Java SE 8以来,Lambda表达式允许声明其形式参数而不使用显式类型。如果var用于lambda表达式的任何形式参数,那么它必须用于该lambda表达式的所有形式参数。
tools/launcher
➜JEP330启动单文件源代码程序
增强java启动程序以运行作为Java源代码的单个文件提供的程序,包括通过“shebang”文件和相关技术从脚本中使用。