--- title: Java 10的新特性 tags: - JVM - Java - Java 10 - 新特性 - 局部变量 - 类型推断 - G1 - 不可变集合 categories: - - JVM - Java keywords: 'Java,Java 10,新特性,局部,变量,推断,G1,不可变,集合' date: 2021-05-20 17:11:56 --- 自从Java 9发布时候,时隔半年,Java 10就问世了。这都归功于Oracle对于Java版本发布策略的变化。相比Java 9,Java 10没有引入特别多的变化,这也是因为各个版本间的发布周期变短,使新引入功能的稳定时间变短导致的。 本系列的文章有: - {% post_link nf-java8 %} - {% post_link nf-java9 %} - {% post_link nf-java10 %} - {% post_link nf-java11 %} - {% post_link nf-java12 %} - {% post_link nf-java13 %} - {% post_link nf-java14 %} - {% post_link nf-java15 %} - {% post_link nf-java16 %} ## 局部变量类型推断 局部变量类型推断是Java 10中引入的最值得注意的特性。这个特性实际上就是一个语法糖,可以简化并改善开发者的书写体验。 我们最常诟病Java的地方,就是它的繁琐和冗长。局部类型推断的引入,直接减少了最常使用的变量定义部分的代码长度。例如下面这个示例。 ```java // 在Java 10之前 Map map = new HashMap<>(); // 在Java 10以后 var map = new HashMap(); ``` 从上面这个示例可以看出来,新引入的`var`关键字承担起了定义变量时声明变量类型的功能。`var`关键字指示编译器按照赋值表达式右值的类型来定义左值的类型,换句话说就是随意定义变量而不必指定变量的具体类型。满满的JavaScript即视感。 可能对于上面这个示例对于代码量的缩减并没有那么直观的感受,那么以下再引申一个示例出来。 ```java var entries = map.entrySet(); ``` 好了,现在再来对比看一下变量`entries`的类型。 虽然`var`关键字引入了许多方便,但是这个关键字的使用是受到限制的,一般推荐在以下场景中使用: - 局部变量初始化。 - `for`循环的内部索引变量。 - 传统`for`循环声明的变量。 其实从这几个场景可以看出来,关键字`var`所能够应用到的场景,都是类型已经完全确定的位置。所以在以下几个场景里,`var`就不能够使用了。 - 构造函数和方法的参数。 - 方法的返回类型。 - 类中属性定义。 - `catch`表达式。 在这些位置中,变量的类型都是无法确定的,必须要显式声明的。 !!! caution "" 需要注意的是,如果在代码中大量的使用`var`关键字,是比较容易导致代码的可读性变差的。 ## 不可变集合 `java.util.List`、`java.util.Map`和`java.util.Set`这三个接口都增加了一个静态方法`.copyOf()`,可以用来形成不可变集合对象。 ```java var copyList = List.copyOf(originIntList); ``` 这样复制出来的`copyList`是不能做任何修改操作的,如果对其进行了修改,就会抛出`UnsupportedOperationException`。 另一个可以用来形成不可变集合的方法是`java.util.stream.Collectors.toUnmodifiable()`。 ```java var evenList = originIntList.stream() .filter(i -> i % 2 == 0) .collection(Collectors.toUnmodifiableList()); ``` 这个方法可以将一个Stream收集起来变为一个不可变集合。如果要对其形成的集合进行修改,也同样会抛出`UnsupportedOperationException`。 ## Optional Optional系列类增加了一个方法`.orElseThrow()`,用来快速抛出`NoSuchElementException`。在Java 10之前,要在Optional中抛出异常必须显式指定异常的类型。现在新添加的`.orElseThrow()`只是一个常用操作的简化形式。 ## 开源根证书 Oracle在Java 10中开源了根证书,这使得OpenJDK和OracleJDK之前的差距缩小了。这也使得原本在OpenJDK中需要经过大量配置才能够正常工作的诸如TLS等安全功能,变得可以比较便捷地使用。 ## 改进GC G1垃圾收集器是在Java 9中引入的默认GC,在Java 10中通过优化Full GC改善了G1的最坏等待时间,增强了GC的性能。 ## 加入容器化支持 Java 10的JVM可以通过配置感知到自身所处的环境是否是虚拟环境,这对JVM获取系统环境信息的操作有影响。要启用JVM的容器化支持,只能在Linux平台中使用。 新加入的JVM选项`-XX:-UseContainerSupport`可以用来指示JVM启用容器化支持。随着容器化支持一并加入的JVM选项还有以下这些用于精细调整JVM所使用系统资源的选项。 - `-XX:ActiveProcessorCount=n`,指示JVM可以使用的CPU数量。 - `-XX:InitialRAMPercentage`,初始可以用作Java堆内存的系统内存比例。 - `-XX:MaxRAMPercentage`,最大可使用的系统内存比例。 - `-XX:MinRAMPercentage`,最小可使用的系统内存比例。