Java 8 & 9 & 10 & 11 新特性
程序员文章站
2024-03-14 17:58:04
...
Java 8
- Java 8 (又称为 jdk 1.8) 是 Java 语言开发的一个主要版本。 Oracle 公司于 2014 年 3 月 18 日发布 Java 8 ,它支持函数式编程,新的 JavaScript 引擎,新的日期 API,新的Stream API 等。
- Java8 新增了非常多的特性,除了文章里的,主要还有以下几个:
- 默认方法 − 默认方法就是一个在接口里面有了一个实现的方法。
- 新工具 − 新的编译工具,如:Nashorn引擎 jjs、 类依赖分析器jdeps。
- Date Time API − 加强对日期与时间的处理。
- Nashorn, JavaScript 引擎 − Java 8提供了一个新的Nashorn javascript引擎,它允许我们在JVM上运行特定的javascript应用。
1. Lambda 表达式
- Lambda 表达式,也可称为闭包,它是推动 Java 8 发布的最重要新特性。
- Lambda 允许把函数作为一个方法的参数(函数作为参数传递进方法中)。
- 使用 Lambda 表达式可以使代码变的更加简洁紧凑。
- 实质可以理解为函数式接口(只有一个抽象方法的接口)的实例
2. 函数式接口
- 只包含一个抽象方法的接口,成为函数式接口
- 可以通过 Lambda 表达式创建该接口的对象
- 可以在接口上使用
@FunctionalInterface
注解,检查是否是一个函数式接口(若接口内包含大于一个的抽象方法会报错) - Java内置四大核心函数式接口:
函数式接口 | 参数类型 | 返回类型 | 用途 |
---|---|---|---|
Consumer< T > | T | void | 为类型为 T 的对象执行操作,包含方法void accept(T t)
|
Supplier< T > | 无 | T | 返回类型为 T 的对象,包含方法T get()
|
Function< T,R > | T | R | 为类型为 T 的对象执行操作,并返回结果,结果是 R 类型的对象,包含方法R apply(T t)
|
Predicate< T > | T | boolean | 判断类型为 T 的对象是否满足某约束,返回布尔值,包含方法boolean test(T t)
|
3. 方法应用和构造器引用
- 当传递给 Lambda 体的操作,已经有实现的方法了,就可以使用方法引用
- 方法引用可以看作 Lambda 表达式的深层次的表达。换句话说,方法引用就是 Lambda 表达式,也就是函数式接口的一个实例
- 要求:实现接口的抽象方法的参数列表和返回值类型,必须与方法引用的方法的参数列表和返回值类型保持一致
- 格式:
- 对象::实例方法名
- 类::静态方法名
- 类::实例方法名
- 举例:
自己的理解:使用Lambda表达式——函数式接口Consumer
——实现接口里的方法accept
——该方法调用println
,两个方法的返回值和形参列表相同——省略Lambda表达式,改用方法引用
- 构造器引用类似
4. Stream API
- Java8的两个重大改变,一个是Lambda表达式,另一个就是本 Stream API 表达式。Stream 是Java8中处理集合的关键抽象概念,它可以对集合进行非常复杂的查找、过滤、筛选等操作
- Stream 关注的是对数据的运算,与 CPU 打交道
- 集合 关注的是数据的存储,与内存打交道
- Stream有如下三个操作步骤:
一、创建Stream:从一个数据源,如集合、数组中获取流。
二、中间操作:一个操作的中间链,对数据源的数据进行操作(过滤、映射、排序······)
三、终止操作:一个终止操作,执行中间操作链,并产生结果。之后,该 Stream 不能再次被使用 - 注意:
- Stream 不会自己存储元素
- Stream 不会改变源对象,会返回一个持有新结果的新 Stream
- Stream 操作是延迟执行的
5. Optional 类
- Optional 类是一个可以为 null 的容器对象。如果值存在则
isPresent()
方法会返回 true,调用get()
方法会返回该对象。 - Optional 是个容器:它可以保存类型 T 的值,或者仅仅保存 null。Optional 提供很多有用的方法,这样我们就不用显式进行空值检测。
- Optional 类的引入很好的解决空指针异常。
- java.util.Optional 类的声明:
public final class Optional<T> extends Object
- 常用 API:
static <T> Optional<T> empty() //返回空的 Optional 实例。
static <T> Optional<T> of(T value) //返回一个指定非null值的Optional。
static <T> Optional<T> ofNullable(T value) //如果为非空,返回 Optional 描述的指定值,否则返回空的 Optional。
T orElse(T other) //如果存在该值,返回值, 否则返回 other。
//......
Java 9
1. jdk 目录结构变化
- jdk8:
- jdk9 及以后:
2. 模块化系统:Jigsaw 项目
- Java 9 最大的变化之一是引入了模块系统(Jigsaw 项目)
- 模块就是代码和数据的封装体。模块的代码被组织成多个包,每个包中包含Java类和接口;模块的数据则包括资源文件和其他静态信息。
- Java 9 模块的重要特征是在其工件(artifact)的根目录中包含了一个描述模块的 module-info.class 文 件。 工件的格式可以是传统的 JAR 文件或是 Java 9 新增的 JMOD 文件。这个文件由根目录中的源代码文件 module-info.java 编译而来。该模块声明文件可以描述模块的不同特征。
- 在 module-info.java 文件中,我们可以用新的关键词module来声明一个模块
3. JShell
- REPL(Read Eval Print Loop)意为交互式的编程环境。
- JShell 是 Java 9 新增的一个交互式的编程环境工具。它允许你无需使用类或者方法包装来执行 Java 语句。它与 Python 的解释器类似,可以直接 输入表达式并查看其执行结果。
4.接口的私有方法
之前:
- 在 Java 8之前,接口可以有常量变量和抽象方法。
- 我们不能在接口中提供方法实现。如果我们要提供抽象方法和非抽象方法(方法与实现)的组合,那么我们就得使用抽象类。
- 在 Java 8 接口引入了一些新功能——默认方法和静态方法。我们可以在Java SE 8的接口中编写方法实现,仅仅需要使用 default 关键字来定义默认方法。
- 注意:接口的静态方法只能由接口调用,接口的实现类不能调用接口的静态方法
- 在 Java 8 中,一个接口中能定义如下几种变量/方法:常量、抽象方法、默认方法、静态方法
Java 9:
- Java 9 不仅像 Java 8 一样支持接口默认方法,同时还支持私有方法。
- 在 Java 9 中,一个接口中能定义如下几种变量/方法:常量、抽象方法、默认方法、静态方法、私有方法、私有静态方法
5. 钻石操作符升级
- 钻石操作符是在 java 7 中引入的,通过类型推断,可以让代码更易读,但它不能用于匿名的内部类。
- 在 Java 8 以下代码会编译报错:
Cannot use <> with anonymous inner class
Comparator<Object> com = new Comparator<>(){
@Override
public int compare(Object o1, Object o2){
return 0;
}
};
- 但是在 Java 9 里面就可以了
6. try 语句升级
- try-with-resources 是 JDK 7 中一个新的异常处理机制,它能够很容易地关闭在 try-catch 语句块中使用的资源。所谓的资源(resource)是指在程序完成后,必须关闭的对象。
- try-with-resources 语句确保了每个资源在语句结束时关闭。所有实现了 java.lang.AutoCloseable 接口(其中,它包括实现了 java.io.Closeable 的所有对象),可以使用作为资源。
- 注意:要求自动关闭的资源的初始化必须在 try 的一对小括号里面
- try-with-resources 声明在 JDK 9 已得到改进。如果你已经有一个资源是 final 或等效于 final 变量,您可以在 try-with-resources 语句中使用该变量,而无需在 try-with-resources 语句中声明一个新变量。
- 注意:此时资源不能在 try 语句块里面更改(final)
7. String 存储结构变更
- String 字符串的底层存储由 char 数组改为 byte 数组加上编码标记,节约了一部分空间
- StringBuffer 与 StringBuilder 对应的存储方式也发送改变,改为 byte 数组存储
8.集合工厂方法
- 在 Java 9 的 List,Set 和 Map 接口中,新的静态工厂方法可以创建这些集合的不可变实例(只读)。这些工厂方法可以以更简洁的方式来创建集合。
之前:Collections.unmodifiableSet
Set<String> set = new HashSet<>();
set.add("A");
set.add("B");
set.add("C");
set = Collections.unmodifiableSet(set);
System.out.println(set);
注意:Array.asList()
方法也是创建只读集合
现在:Java 9 中,以下方法被添加到 List,Set 和 Map 接口以及它们的重载对象。List 和 Set 接口, Map 接口的 of(...)
方法重载了 0 ~ 10 个参数的不同方法 。Map 接口如果超过 10 个参数, 可以使用 ofEntries(…) 方法。
static <E> List<E> of(E e1, E e2, E e3);
static <E> Set<E> of(E e1, E e2, E e3);
static <K,V> Map<K,V> of(K k1, V v1, K k2, V v2, K k3, V v3);
新方法创建集合:
Set<String> set = Set.of("A", "B", "C");
System.out.println(set);