本文是对底部参考资料的整理获得的,因为本人技术水平和英语水平都不是很高,有些词若有翻译错误或句子的理解错误还请指出。
var
传统的 Java 代码中,声明一个变量是很是繁琐的:html
List<String> list = new ArrayList<String>();
如今则引入了 var
,既保持 Java 对静态类型安全的承诺,又能让开发者省略没必要要的局部变量类型的声明。java
好比像这样:程序员
var list = new ArrayList<String>();
var
只能用在如下状况:算法
for
循环中的索引 (这将在后面提到)for
循环中声明的本地变量它不能被用于方法签名、构造器声明、方法返回类型、字段、异常捕获或任何其余类型的变量声明。数组
类型推断在 Java 8 中已经获得了显著的扩展,包括了对嵌套和连接的泛型方法的推导以及 lambda 表达式的推导,好比下面这样:安全
int maxWeight = blocks.stream() .filter(b -> b.getColor() == BLUE) .mapToInt(Block::getWeight) .max();
没有必要去在乎 blocks.stream*()
返回的是 Stream<Block>
,也不用在乎 filter
中 lambda 表达式的参数类型没有被显式声明,由于它们都能经过类型推导获得。oracle
对于局部类型变量,类型推导是很是有用的,由于一般状况下均可以写成下面这种代码:框架
var path = Paths.get(fileName); var bytes = Files.readAllBytes(path);
可是要注意的是,var
并非一个关键字,而是一个保留的类型名称,这意味着你能够将一个变量、方法、包名写成 var
。不过通常状况下不会有人这么写的,由于这自己就违反了广泛的命名规范。工具
var
不能用来声明没有赋值的变量、不能用于声明多个变量的状况、不能声明具备额外纬度的数组或引用了正在初始化的其余变量的变量。oop
JEP 223 引入的版本号方案相比以前的方法都要好不少,可是对于如今 Java 所走的 六个月节奏 并不适合。
JEP 223 的问题在于,版本号中编码了它和它对以前版本的兼容性信息。可是在 六个月节奏 的状况下,这些信息都是未知的,在发布前任何事情均可能发生,由此 JEP 223 规范下的版本号也会是未知的。
在 JEP 223 的语义中,每一个基于 JDK 构建或使用组件的开发者(包括 JDK 的发布者)都必须提早敲定版本号,而后切换过去。而库、框架和工具的开发者则必须在代码中修改检查版本号的相关代码,这形成了混乱。
更多关于 JEP 322 的详细状况请访问这里。
core-libs/java.util
Optional.orElseThrow()
方法这次更新中为 Optional
类添加了一个新的方法,这个方法与 orElseThrow(exSupplier)
是不一样的,它没有参数。
Optional.get()
是一个容易误导程序员的方法,它实际上有可能抛出 NoSuchElementException
运行时异常,所以须要一个语义明确的方法来帮助程序员清楚的认识到本身在作什么。
在以前的规划中,Optional.getWhenPresent()
是一个备选方法,虽然这个名字强调了值必定会存在,可是其中的 when
彷佛会让人以为这是个阻塞方法。所以最后委员会选择了 Optional.orElseThrow()
,可是 Optional.get()
并无被单纯得弃用。
加强了 java.util.Locale
和相关 API 以实现关于 BCP 47 语言标签 的 Unicode 扩展。
详情请访问这里
core-libs/java.util
建立不可变集合的一系列 API 新的 API 中包括了一些用于建立不可见集合的方法:
List.copyOf
、Set.copyOf
和 Map.copyOf()
能够用来从已有的集合中建立一个新的集合;
toUnmodifiableList
、toUnmodifiableSet
和 toUnmodifiableMap
则存在于 Stream.Collectors
类中,经过它们能够将流的元素收集到一个不可变集合当中。
copyOf
系列的方法签名基本是下面这样:
static <T> List <T> copyOf (Collection <? extends T> coll)
Set
和 Map
也会有相似的方法。
值得注意的是,这个方法会检测 coll
是否是一个 不可变 的集合,若是是,则会直接返回该引用,至关于一个浅拷贝。
另外对于不可变集合而言,下面这种状况是被容许的:
List <String> list = List.of(...); List <CharSequence> newList = List.copyOf(list);
这对于可变集合而言是不容许的,由于这可能会致使堆污染。
core-svc/java.lang.management
用于关闭 JRE Last Usage Tracking 的系统属性引入了新的 jdk.disableLastUsageTracking
属性以禁用 JVM
的 JRE 上次使用状况追踪 功能。
若是使用了此属性,那么 com.oracle.usagetracker.track.last.usage
的设置将被忽略。
core-svc/java.lang.management
开箱即用的 JMX 代理使用的散列密码在之前,JMX 存储的是明文密码,当时 (2014 年) 你们已经开始手动生成散列密码来替换明文密码,由于这能够避免一些攻击,同时盐 (salt) 的存在可让散列密码的强度更上一层。可是对于管理员而言,即便是使用诸如 Python 之类的脚本语言来生成散列密码,这仍然是极容易出错的。所以最好的办法是用户只须要提供明文密码,让 JMX 来处理散列之类的事情。
JMX 如今会使用密码的 SHA3-512 散列结果来覆盖存储在 jmxremote.password
中的明文密码。
其格式以下:
role_name W hashedPassword
其中:
role_name
是任何不含空格或制表符的字符串W
是一个空格或制表符散列密码的格式以下:
hashedPassword = base64_encoded_64_byte_salt W base64_encoded_hash W hash_algorithm
其中:
base64_encoded_64_byte_salt
是 64字节的随机值base64_encoded_hash
是 Hash_algorithm(password + salt)
的结果W
是一个空格或制表符hash_algorithm
是列表 中指定的算法名称。这是个可选项,默认值为 SHA3-512
若是密码是明文的,且知足如下条件,那么将被散列值覆盖
management.properties
文件中 com.sun.management.jmxremote.password.toHashes
属性被设为 true
若是想更改角色的密码,能够将旧的散列密码替换为新的明文密码或新的散列密码。若是新的密码是明文的,那么在新的登陆发生时系统会使用其散列值替换明文密码。
文件中的角色应该至少有一条记录,不然该角色将无权访问;若是同一个用户下有多条记录,那么会使用最后一条记录。
用户能够自行根据上述的格式来生成的散列值,以替换旧的密码。
文件被拥有者之外的用户访问时将致使错误并退出程序。
为了防止在生产环境中对密码文件进行了无心的编辑,建议只部署可读的散列密码文件。明文密码的散列密码列表能够用 JMX 代理预先生成。
在 JMX 运行期间,建议不要编辑密码文件。程序会对文件的完整性作一个保护,所以修改既可能丢失。
hotspot/gc
JEP 307 G1 的 彻底并行 GC G1 垃圾收集器就是为了不 彻底 GC (full collections) , 可是当并行收集没法快速回收内存时,会产生一次 彻底回退 GC (fall back full GC) 。
以前 G1 的 彻底GC 使用的是单线程标记扫描压缩算法(mark-sweep-compact),如今经过 JEP 307,彻底GC 得以并行化,同时如今会使用与 年轻代 、混合收集 相同的并行工做线程数量。
security-libs/java.security
JEP 319 根证书OpenJDK 中的 cacerts 密钥库在至关长一段时间内是空的,这将致使未指定 javax.net.ssl.trustStore
属性的状况下 TLS 链接 的建立会被阻止。如今Oracle
的 Java SE 根证书 被填充至 OpenJDK 的 cacerts 中。
security-libs/javax.net.ssl
TLS 会话散列 和 主密钥扩展 的支持在是一个对 RFC 7627 的支持。
若是出现兼容问题,能够将 jdk.tls.useExtendedMasterSecret
设置为 false
来禁用此扩展的协商。
若是 jdk.tls.allowLegacyResumption
值为 false
,当会话散列和主密钥扩展未协商的状况下,程序能够拒绝简短握手。
若是 jdk.tls.allowLegacyMasterSecret
值为 false
,应用将拒毫不支持此扩展的链接。
tools/javac
加强 for
循环的字节码生成以前的 for
循环在遍历一个大的列表/数组时,它会隐式得持有一个临时引用,并且这个临时引用不会被释放以致于可能产生 OutOfMemoryError
异常,详细的状况能够查看这里。
对于下面的 Java 代码:
List<String> data = new ArrayList<>(); for (String b : data);
将会被编译为:
{ /*synthetic*/ Iterator i$ = data.iterator(); for (; i$.hasNext(); ) { String b = (String) i$.next(); } b = null; i$ = null; }
这意味着 GC 能够发现再也不被使用的 i$
所占用的内存并回收它,这对于数组也是适用的。
tools/javadoc(tool)
javadoc 支持多个样式表新的 javadoc 命令行选项 --add-stylesheet
,它支持在生产的文档中使用多个样式表。
而现有的选项 -stylesheetfile
有了一个别名 stylesheetfile --main-stylesheet
,用以区分主样式表和其余样式表,更多信息能够查看 javadoc 文档。
tools/javadoc(tool)
覆写没有改变规范的方法默认状况下,若是有方法覆写了超类中的方法,那么 javadoc 会为它生成文档。
可是若是一个方法只是被覆写可是没有改变语义行为时,javadoc 只会在原方法摘要中用 @inheritdoc
标记它。
如今新的选项 --overridden-methods=value
能够将许多 不改变规范的覆写方法 与其余继承而来的方法分组,而不是在类的声明中与其余方法一块儿被记录在文档中。
tools/javadoc(tool)
API 描述中摘要的注释标记{@summary ...}
是一个新的行内标记。默认状况下,会经过简单算法或 java.text.BreakIterator
对描述中的第一句话进行判断以肯定 API 描述内容的摘要,可是这种方法可能会对第一句话结尾有错误的判断,所以新的标签能够显式得指定 API 的描述摘要。
参考资料
- JDK 10 Release Notes
- Java SE 10 (18.3) ( JSR 383) Final Release Specification
- JEP 286 Local-Variable Type Inference
- JEP 322: Time-Based Release Versioning
- JEP 314: Additional Unicode Language-Tag Extensions
- JDK-8140281 : (opt) add no-arg orElseThrow() as preferred alternative to get()
- JDK-8177290 : add copy factory methods for unmodifiable List, Set, Map
- JDK-5016517 : Replace plaintext passwords by hashed passwords for out-of-the-box JMX Agent
- JDK-8172890 : JEP 307: Parallel Full GC for G1
- JDK-8189131 : Open-source the Oracle JDK Root Certificates
- JDK-8148421 : Transport Layer Security (TLS) Session Hash and Extended Master Secret Extension
- JDK-8175883 : bytecode generated for the enhanced for loop may block memory garbage collecting
- JDK-8185371 : Support for multiple stylesheets in javadoc
- JDK-8157000 : Do not generate javadoc for overridden method with no spec change
- JDK-8173425 : Javadoc needs a new tag to specify the summary.