Java核心新特性
1. JDK 9~17
新特性
1.1. 密封类(JDK 17
)
密封类使用
sealed
声明并用permits
列出可扩展它的类型,能够限制继承或实现它的其它类或接口
1.1.1. 语法结构
[modifier] sealed class ClassName permits TypeList {
...
}
- TypeList:类型列表,可扩展当前类的类型
说明
- 密封类的子类必须使用
final
、sealed
或non-sealed
修饰
1.2. record类型(JDK 16
)
record
是一种全新的类型,本质上是一个final
类且所有的属性都用final
修饰,且自动编译出public get
、hashcode
、equals
、toString
、构造器等
1.2.1. 语法结构
[modifier] record RecordName(fieldList) {
...
}
- fieldList:属性列表,默认为,中间用
,
隔开
说明
- 可以定义静态字段、静态方法、构造器或实例方法
- 不能使用abstract修饰且不能声明实例字段
1.3. instanceof模式匹配(JDK 16
)
判断对象是否时指定类的实例,如果是则强制类型转换并重命名
obj instanceof ClassName c
1.4. switch结构(JDK 14
)
1.4.1. swtich表达式
- 使用
->
替换:
(不共存),只有匹配分支的语句(块)被执行且有返回值 - 多个分支执行相同操作可将多个分支合并,常量间用
,
隔开 - 语句块配合
yield
语句跳出当前switch
并返回相应的值
1.4.2. switch模式匹配(JDK 17
预览)
在匹配变量类型后进行重命名
switch(o) {
case Class1 c1: ...
case Class2 c2: ...
...
Case ClassN cN: ...
[default: ...]
}
1.5. 局部变量类型推断(JDK 10
)
根据上下文,编译器能够确定类型的局部变量可以用var
关键字定义
适用场景
- 声明局部变量并初始化
- 定义for循环的索引
- 定义变量泛型结构的返回值
不适用场景
- 声明成员变量
- 声明数组并静态初始化(省略
new
) - 方法的返回值、参数类型
- 声明局部变量但不初始化
- 声明catch语句的异常类型
- 声明Lambda表达式、方法引用的函数式接口类型
1.6. 其他特性
- JDK 15
:文本块,使用"""
作为开始符和结束符,无需转义- JDK 11
:简化编译运行,java src.java
- JDK 9
: REPL工具jShell,交互式编程环境
2. JDK 6~8
新特性
2.1. 函数式接口(JDK 8
)
只包含一个抽象方法(Single Abstract Method,SAM)的接口
- Java 8的函数式接口定义在
java.util.function
包下 @FunctionalInterface
注解用于检查函数式接口- 函数式接口可以使用Lambda表达式进行实例化
2.1.1. 核心函数式接口
函数式接口 | 称谓 | 方法 | 说明 |
---|---|---|---|
Consumer | 消费型 | void accept(T t) | 对T类型的对象应用操作 |
Supplier | 供给型 | T get() | 返回T类型的对象 |
Function<T, R> | 函数型 | R apply(T t) | 对T类型的对象应用操作,并返回R类型的对象 |
Predicate | 判断型 | boolean test(T t) | 确定T类型的对象是否满足某约束 |
2.1.2. 常见函数式接口
函数式接口 | 方法 |
---|---|
java.lang.Runnable | void run() |
java.lang.Iterable | Iterator iterate() |
java.lang.Comparable | int compareTo(T t) |
java.util.Comparator | int compare(T t1, T t2) |
2.2. lambda表达式
Lambda表达式是一个匿名函数,提供了一种实例函数式接口实现类的方式
语法格式
(params) -> {
body
}
->
:Lambda操作符,也成为箭头操作符- params:Lambda表达式的参数列表,对应抽象方法的参数列表,其规则为
- 参数类型可推断则可省略类型
- 只有一个参数可省略
()
,其他情况不可省略
- body:Lambda表达式的函数体,对应抽象方法的方法体,其规则为
- 只有一条语句可省略
{}
,同时应省略返回语句的return
- 只有一条语句可省略
2.3. 方法引用(JDK 8
)
方法引用是Lambda的简化(语法糖),用于实例函数式接口实现类
2.3.1. 前提条件
- Lambda表达式的函数体只有一条语句且是方法调用
2.3.2. 语法格式
静态方法引用
若抽象方法与静态方法的返回值、形参类型相同或兼容
ClassName::staticMethod
- ClassName:类名
- staticMethod:静态方法名
实例方法引用
若抽象方法与实例方法的返回值类型相同或兼容,形参列表满足
-
抽象方法与实例方法的形参类型相同或兼容
objName::instanceMethod
- objName:对象名
- instanceMethod:实例方法名
-
抽象方法的首个形参调用实例方法,其他形参与实例方法类型相同或兼容
ClassName::instanceMethod
构造器引用
若抽象方法的返回某个类类型,形参类型与该类的某个构造器相同或兼容
ClassName::new
数组引用
若抽象方法的返回某类型的数组,形参为数组的长度
ArrayType::new
- ArrayType:数组类型名
2.4. Stream API(JDK 8
)
Stream API是操作数据源(集合、数组等)所生成的元素序列的工具
- Stream本身不会存储元素
- 所有操作都不改变源对象,而是返回操作结果的流表示
- 操作是延迟执行的,即需要结果时才执行
- 执行终止操作后不能再执行其他中间操作或终止操作
2.4.1. 操作步骤
- 创建流:从数据源(集合、数组等)获取一个流
- 中间操作:对流数据进行处理并返回结果的流(支持操作链)
- 终止操作:操作流数据但返回结果不再是流,故会终止流操作
2.4.2. 创建Stream实例
通过集合
- 获取顺序流:调用Collection对象的stream方法
- 获取并行流:调用Collection对象的parallelStream方法
通过数组
- 调用Arrays类的静态方法stream
说明
- 若数组的元素类型为基本数据类型xxx,则返回XxxStream实例
通过Stream类
- 调用Stream类的静态方法of
2.4.3. 常用API
中间操作
方 法 | 描 述 |
---|---|
Stream filter(Predicate<? super T> predicate) | 过滤流中predicate匹配的元素 |
Stream distinct() | 去除重复元素(用hashCode和equals方法判断) |
Stream limit(long maxSize) | 元素个数超过maxSize时截断流 |
Stream skip(long n) | 跳过n个元素 |
Stream map(Function<? super T, ? extends R> mapper) | 返回应用mapper后的结果组成的流 |
Stream mapToXxx(ToXxxFunction<? super T> mapper) | 返回应用mapper后的结果组成的Xxx流 |
Stream sorted() | 返回元素自然排序后的流 |
Stream sorted(Comparator<? super T> comparator) | 返回元素按照comparator排序后的流 |
终止操作
方 法 | 描 述 |
---|---|
boolean allMatch(Predicate<? super T> predicate) | 判断元素是否都匹配predicate |
boolean anyMatch(Predicate<? super T> predicate) | 判断元素是否存在元素匹配predicate |
boolean noneMatch(Predicate<? super T> predicate) | 判断元素是否不存在元素匹配predicate |
Optional findFirst() | 返回第一个元素 |
Optional findAny() | 返回任意元素 |
Optional max(Comparator<? super T> comparator) | 返回最大元素(根据comparator比较) |
Optional min(Comparator<? super T> comparator) | 返回最小元素(根据comparator比较) |
long count() | 返回元素的个数 |
void forEach(Consumer<? super T> action) | 对所有元素执行action指定的操作 |
Optional reduce(BinaryOperator accumulator) | 返回按照accumulator规约后的元素 |
<R, A> R collect(Collector<? super T, A, R> collector) | 使用collector存储流中的元素 |
2.5. Optional类(JDK 8
)
Optional是一个容易类,用于保存T类型的值,表示其存在;或保存null,表示其不存在
2.5.1. 实例化
Optional<T> optional = offNullable(T value);
2.5.2. 常用API
常用方法
方 法 | 描 述 |
---|---|
static Optional empty() | 返回一个空的容器实例 |
static Optional of(T value) | 返回包含非空值value的容器实例 |
static Optional ofNullable(T value) | 返回包含值value的容器实例 |
boolean isPresent() | 判断容器中的元素是否存在 |
void ifPresent(Consumer<? super T> consumer) | 若容器中的元素存在则执行指定操作,否则不执行 |
T get() | 获取容器中的元素 |
T orElse(T other) | 若容器中元素非空则返回,否则返回other |
T orElseGet(Supplier<? extends T> other) | 若容器中元素非空则返回,否则返回other |
T orElseThrow(Supplier<? extends X> exceptionSupplier) | 若容器中元素非空则返回,否则抛出异常 |
2.6. try-catch关闭资源(JDK 7
)
try(rsrcList) {
...
} catch() {
...
}
- rsrcList:自动关闭资源的声明和创建,使用
final
修饰
说明
JDK 9
允许使用资源变量名构成资源列表,多个变量名之间使用;
隔开- 自动关闭资源的类必须实现
AutoCloseable
或Closeable
接口的close()方法 - 资源列表中的变量使用final修饰,不能更改