概述

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

    1. http://openjdk.java.net/projects/jdk/10

    12个JEP

    image.png

    Java 10 下载安装

    下载

    1. https://www.oracle.com/java/technologies/java-archive-javase10-downloads.html

    安装

    在官网下载完成后就是一个安装包,双击启动
    image.png
    image.png
    image.png
    image.png
    image.png
    image.png
    image.png

    IDEA集成JDK10

    image.png
    在创建项目的时候下面会自动扫描到,点击即可选择
    顺手创建个项目..这个就不截图了,应该都懂

    局部变量类型推断(主打功能)

    产生背景

    开发者经常抱怨Java中引用代码的程度,局部变量的显示类型声明,常常被认为是不必须的,给一个好听的名字经常可以很清楚的表达出下面应该怎样继续

    好处

    减少了啰嗦和形式的代码,避免了信息冗余,而且对齐了变量名,更容易阅读

    举例如下

  • 场景1

    • 作为Java开发者, 在声明一个变量时,我们总是习惯了敲打两次变量类型,第一次用于声明变量类型,第二次用于构造器
      LinkedHashSet<String> set = new LinkedHashSet<>();
      
  • 场景2

    • 变量的声明类型书写复杂且较长,尤其是加上泛型的使用
      Iterator<Map.Entry<Integer,String>> iterator = set.iterator();
      
  • 场景3

    • 我们也经常声明一种变量,它只会被使用一次,而且是下一行代码中比如:
      URL url = new URL("http://www.atguigu.com");
      URLConnection urlConnection = url.openConnection();
      
      尽管IDE可以帮助我们自动完成这些代码,但是当变量总是跳来跳去的时候,可读性还是会受到影响,因为变量类型的名称由各种不同长度的字符组成,而且有时候开发人员会尽力避免声明中间变量,因为太多的类型名称只会分散注意力,不会带来额外的好处

      代码(可以用)

      ```java // 声明变量时,根据所附的值,推断声明类型 // 我感觉就是把前端的var 拿了过来~~ 但是没有完全拿过来 var x = 10; var y = 20; System.out.println(x + y);

// 定义泛型的时候在Java8的时候可以省略右侧的,现在左侧可以变成var 那么就要在右侧,不然推断出来的是Object var list = new ArrayList(); list.add(“dance”);

// 遍历操作 for (var s : list) { System.out.println(s); }

for (var i = 0; i < 2; i++) { System.out.println(i); }

虽然可以用,但是我感觉谁要在项目里面写,绝对会被打死AQA
<a name="DHO2r"></a>
## 无法推断的类型
<a name="OqnA9"></a>
### 无法推断null
![image.png](https://cdn.nlark.com/yuque/0/2022/png/1603133/1646320686544-f105b84d-9e80-4bc9-b6e8-4ededa08983f.png#clientId=ubefd36c4-9cd4-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=79&id=uefdb9fb7&margin=%5Bobject%20Object%5D&name=image.png&originHeight=99&originWidth=393&originalType=binary&ratio=1&rotation=0&showTitle=false&size=5382&status=done&style=none&taskId=udc0a0544-0103-477d-afff-2b280bf8b37&title=&width=314.4)
<a name="ZgYzU"></a>
### 无法之定义声明
![image.png](https://cdn.nlark.com/yuque/0/2022/png/1603133/1646320749037-a51d16dc-8cdc-4a43-be45-8c2831159daf.png#clientId=ubefd36c4-9cd4-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=76&id=u6409378c&margin=%5Bobject%20Object%5D&name=image.png&originHeight=95&originWidth=470&originalType=binary&ratio=1&rotation=0&showTitle=false&size=5370&status=done&style=none&taskId=u85cd1b9d-09eb-4f10-bde0-91eb73230df&title=&width=376)
<a name="enoDE"></a>
### 无法推断Lambda表达式
![image.png](https://cdn.nlark.com/yuque/0/2022/png/1603133/1646320863750-570b75e8-f23d-458f-b266-ca1a91461589.png#clientId=ubefd36c4-9cd4-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=108&id=u43a2ffbb&margin=%5Bobject%20Object%5D&name=image.png&originHeight=135&originWidth=585&originalType=binary&ratio=1&rotation=0&showTitle=false&size=18688&status=done&style=none&taskId=u87cae2e6-3f4f-4b1a-b583-bf66dadda14&title=&width=468)
<a name="ZTfii"></a>
### 无法推断方法引用
![image.png](https://cdn.nlark.com/yuque/0/2022/png/1603133/1646320920538-23788688-00cc-4a22-bba3-6ac23f2ac2d7.png#clientId=ubefd36c4-9cd4-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=95&id=udd708d0e&margin=%5Bobject%20Object%5D&name=image.png&originHeight=119&originWidth=594&originalType=binary&ratio=1&rotation=0&showTitle=false&size=15018&status=done&style=none&taskId=u7d1d3ac0-827b-4fcc-a19c-ad9478f18e9&title=&width=475.2)
<a name="zEnF5"></a>
### 无法推断显示数组
![image.png](https://cdn.nlark.com/yuque/0/2022/png/1603133/1646320990446-44596dbe-6b64-4f2c-8c6a-3ee40af40a25.png#clientId=ubefd36c4-9cd4-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=41&id=u13be6afa&margin=%5Bobject%20Object%5D&name=image.png&originHeight=51&originWidth=305&originalType=binary&ratio=1&rotation=0&showTitle=false&size=3371&status=done&style=none&taskId=ua1c98dcd-22a5-4b35-b421-cc0a90e60a7&title=&width=244)
<a name="JMy77"></a>
### 其他

1. 没有初始化值
1. 值为null
1. Lambda
1. 方法引用
1. 静态初始化数组
1. 方法的返回值
1. 方法的参数列表
1. 构造器参数列表
1. 属性
1. catch块
<a name="aDJAu"></a>
## 工作原理
在处理var时,编译器先是查看表达式右边部分,并根据右边变量值的类型进行推断,作为左边的变量类型,然后将该类型写入字节码当中
<a name="HvGKJ"></a>
## 注意
<a name="kkok7"></a>
### var 不是一个关键字
你不用担心变量名或者方法名会与var冲突,因为var实际上并不是一个关键字,而是一个类型名,只有在编译器需要知道类型的地方,需要用到它,除此之外,它就是一个标准合法的标识符,也就是说除了不能用它作为类名,其他的都可以,但是极少人会用它作为类名
<a name="UIiQl"></a>
### 这不是JavaScript
首先说明的是,var并不会改变Java是一门静态类型语言的事实,编译器负责断出类型,并把结果写入字节码文件,就好像是开发人员自己敲入类型一样,下面是使用IntelliJ(实际上是Frenflower的反编译器)反编译器反编译出的代码
<a name="HAOIS"></a>
# 集合新增创建不可变集合的方法
自 Java9 开始,JDK里面的集合(List/Set/Map)都添加了of(JDK9新增)和copyOf(JDK10新增)方法,他们两个都用来创建不可变的集合,来看下他们的使用和区别
<a name="MdDT1"></a>
## 代码
```java
var list = List.of("tom", "jetty", "python");
var copy = List.copyOf(list);
System.out.println(list == copy);

var list2 = new ArrayList<>();
var copy2 = List.copyOf(list2);
System.out.println(list2 == copy2);

执行结果

true
false

为什么代码一样,结果不一样呢

因为源码中通过List.of创建的集合,他的类型是AbstractImmutableList类的子类

static <E> List<E> of(E e1, E e2, E e3) {
    return new ImmutableCollections.ListN<>(e1, e2, e3);
}

image.png
然后在调用List.copyOf时,会判断是否属于这个ImmutableCollections.AbstractImmutableList

static <E> List<E> copyOf(Collection<? extends E> coll) {
    if (coll instanceof ImmutableCollections.AbstractImmutableList) {
        return (List<E>)coll;
    } else {
        return (List<E>)List.of(coll.toArray());
    }
}

如果属于,会直接强制类型转换为这个泛型返回结果,其实内存地址是没有发生改变的
但是后面的通过new ArrayList(),类型不是AbstractImmutableList的子类,所以在调用copyOf的时候,是通过List.of创建了一个新的对象,所以是FALSE
image.png
它和ArrayList是平级关系,都继承于AbstractList,这个其实就是一个只读集合,List.copyOf的方法的意思就是,如果入参是一个只读集合,那么就直接返回,如果不是,那么久创建一个只读集合返回