一、JDK10 发布

2018年3月21日, Oracle官方宣布Java10正式发布。
需要注意的是 Java 9 和 Java 10 都不是 LTS (Long-Term-Support) 版本。和过去的 Java 大版本升级不同,这两个只有半年左右的开发和维护期。而未来的 Java 11,也就是 18.9 LTS,才是 Java 8 之后第一个 LTS 版本。
JDK10一共定义了109个新特性, 其中包含12个JEP(对于程序员来讲, 真正的新特性其实就一个) , 还有一些新API和JVM规范以及JAVA语言规范上的改动。
JDK10的12个JEP(JDK Enhancement Proposal特性加强提议) 参阅官方
文档:http://openjdk.java.net/projects/jdk/10/

二、JDK10中的12个JEP

Java10新特性 - 图1

三、局部变量类型推断

1、背景

产生背景:开发者经常抱怨Java中引用代码的程度。 局部变量的显示类型声明,常常被认为是不必须的,给一个好听的名字经常可以很清楚的表达出下面应该怎样继续。
好处:减少了啰嗦和形式的代码,避免了信息冗余,而且对齐了变量名,更容易阅读!

2、举例

场景一:类实例化时
作为 Java开发者, 在声明一个变量时, 我们总是习惯了敲打两次变量类型, 第一次用于声明变量类型, 第二次用于构造器。

  1. LinkedHashSet<Integer> set = new LinkedHashSet<>();

场景二:返回值类型含复杂泛型结构
变量的声明类型书写复杂且较长,尤其是加上泛型的使用

  1. Iterator<Map.Entry<Integer, Student>> iterator = set.iterator();

场景三:
我们经常声明一种变量,它只会被使用一次,而且是用在下一行代码中,比如:

  1. URL url = new URL("http://www.baidu.com");
  2. URLConnection connection = url.openConnection();
  3. Reader reader = new BufferedReader(new
  4. InputStreamReader(connection.getInputStream()));

尽管 IDE可以帮我们自动完成这些代码,但当变量总是跳来跳去的时候,可读性还是会受到影响,因为变量类型的名称由各种不同长度的字符组成。而且,有时候开发人员会尽力避免声明中间变量,因为太多的类型声明只会分散注意力,不会带来额外的好处。

3、局部变量类型推断

适用于以下情况:

  1. //1.局部变量的初始化
  2. var list = new ArrayList<>();
  3. //2.增强for循环中的索引
  4. for(var v : list) {
  5.   System.out.println(v);
  6. }
  7. //3.传统for循环中
  8. for(var i = 0;i < 100;i++) {
  9.   System.out.println(i);
  10. }

在局部变量中使用时,如下情况不适用:
① 初始值为 null
Java10新特性 - 图2
② Lambda 表达式
Java10新特性 - 图3
③ 方法引用
Java10新特性 - 图4
④ 为数组静态初始化
Java10新特性 - 图5
不适用以下的结构中:
① 没有初始化的局部变量声明;
② 方法的返回类型
③ 方法的参数类型
④ 构造器的参数类型
⑤ 属性
⑥ catch 块

4、工作原理

工作原理
在处理 var 时,编译器先是查看表达式右边部分,并根据右边变量值的类型进行推断,作为左边变量的类型,然后将该类型写入字节码当中。
注意:
var不是一个关键字
你不需要担心变量名或方法名会与 var发生冲突, 因为 var实际上并不是一个关键字,而是一个类型名, 只有在编译器需要知道类型的地方才需要用到它。 除此之外, 它就是一个普通合法的标识符。 也就是说, 除了不能用它作为类名, 其他的都可以,但极少人会用它作为类名。
这不是 JavaScript
首先我要说明的是, var并不会改变Java是一门静态类型语言的事实。 编译器负责推断出类型, 并把结果写入字节码文件, 就好像是开发人员自己敲入类型一样。下面是使用 IntelliJ(实际上是 Fernflower的反编译器)反编译器反编译出的代码:**Java10新特性 - 图6

四、集合新增创建不可变集合的方法

自 Java 9 开始, Jdk 里面为集合(List / Set / Map) 都添加了 of (jdk9新增)和copyOf (jdk10新增)方法, 它们两个都用来创建不可变的集合, 来看下它们的使用和区别。
Java10新特性 - 图7
从 源 码 分 析 ,可 以 看 出 copyOf 方 法 会 先 判 断 来 源 集 合 是 不 是AbstractImmutableList 类型的, 如果是,就直接返回,如果不是,则调用 of 创建一个新的集合。
示例2因为用的 new 创建的集合, 不属于不可变 AbstractImmutableList 类的子类,所以 copyOf 方法又创建了一个新的实例, 所以为false。
注意:使用of和copyOf创建的集合为不可变集合, 不能进行添加、 删除、 替换、排序等操作, 不然会报 java.lang.UnsupportedOperationException 异常。
上面演示了 List 的 of 和 copyOf 方法, Set 和 Map 接口都有。