# java10特性

## 语法变更

### 局部变量类型推断

局部变量的显示类型声明，常常认为是不必须的，而Java中，在声明一个变量时，需要书写两遍变量的类型：

```java
ArrayList<String> list = new ArrayList<>();
```

如果变量类型书写复杂且较长，尤其是加上泛型后，声明语句将会变得更加复杂。所以java10中，提供了局部变量的类型推断。在java10之前，可以通过lombok的`@var`注解来完成类似的功能。

```java
var a = 10; // 根据等号后面的数据类型，推断变量的数据类型为10
var date = new Date(); // 推断类型为Date

// 没有初始值，无法推断
var c; // 报错

// null值，无法推断
var d = null; // 报错

// lambda 无法辨别匿名内部类的类型，无法推断
var supplier = () -> Math.random(); // 报错

// 方法返回值不可推断
public var test(); // 报错

// 方法的参数不可推断
public void test2(var data); // 报错

// 成员变量不可推断
class Person {
    private var name;
}

// catch块不可推断
try {} catch (var e) {}
```

> 1. 仅仅可以推断局部变量
> 2. var不是关键字，var可以作为变量名，但是不建议使用

## API变更

### 集合新增copyOf方法创建只读集合

在Java9中提供了`List.of()`方法用于创建只读集合，Java10中又提供了`copyOf`方法创建。他的作用主要是拷贝一个集合让其产生一个新的只读集合。如果被拷贝的集合本身就是只读集合，则返回他本身：

```java
// 拷贝一个集合让其产生一个新的只读集合
var numbers1 = new ArrayList<Integer>();
var numbers2 = List.copyOf(numbers1);
System.out.println(numbers1 == numbers2); // false

// 如果被拷贝的集合本身就是只读集合，则返回他本身
var strings1 = List.of("a", "b", "c");
var strings2 = List.copyOf(strings1);
System.out.println(strings1 == strings2); // true
```
