Java 8
新特性
Lambda 表达式和函数式接口
Lambda 表达式是一种匿名函数,允许将函数作为参数传递给方法,或者在集合操作中以更紧凑的方式编写代码。函数式接口是只有一个抽象方法的接口,可隐式转换为 Lambda 表达式。Java 8 提供了 @FunctionalInterface
注解来显式说明某个接口是函数式接口。
示例:
java
import java.util.Arrays;
import java.util.List;
public class LambdaDemo {
public static void main ( String [] args ) {
List < String > names = Arrays.asList( "Alice", "Bob", "Charlie" );
// Java 7 及之前使用匿名类遍历列表
for ( String name : names ) {
System.out.println( name );
}
// Java 8 使用 Lambda 表达式遍历列表
names.forEach( name -> System.out.println( name ) );
}
}
传统方式与新特性对比:传统方式使用匿名类,代码冗长;Lambda 表达式简化了代码结构,避免了匿名类的冗余代码。
接口的默认方法和静态方法
Java 8 允许在接口中定义默认方法和静态方法。默认方法使得开发者可以在不破坏二进制兼容性的前提下,往现存接口中添加新的方法,不强制实现类实现该方法。静态方法可以直接通过接口调用。
示例:
java
interface Formula {
double calculate ( int a);
default double sqrt ( int a) {
return Math.sqrt(a);
}
}
public class Main {
public static void main(String[] args) {
Formula formula = new Formula() {
@Override
public double calculate ( int a) {
return sqrt(a * 100);
}
};
formula.calculate( 100); // 100.0
formula.sqrt( 16); // 4.0
}
}
Stream API
Stream API 提供了一种声明式的方式来处理集合数据,支持流式处理、懒加载和并行计算。可以对集合进行过滤、映射、归约等操作。
示例:
java
import java.util.Arrays;
import java.util.List;
public class StreamDemo {
public static void main ( String [] args ) {
List < Integer > numbers = Arrays.asList( 1, 2, 3, 4, 5, 6 );
// Java 7 及之前使用循环过滤偶数并打印
for ( Integer number : numbers ) {
if ( number % 2 == 0 ) {
System.out.println( number );
}
}
// Java 8 使用 Stream API 过滤偶数并打印
numbers.stream().filter(n -> n % 2 == 0).forEach(System.out::println);
}
}
传统方式与新特性对比:传统方式使用循环遍历,代码繁琐,缺乏可读性;Stream API 提供了更加简洁、功能强大的数据操作方法,可以通过链式调用实现复杂的操作。
使用场景
- Lambda 表达式和函数式接口:适用于集合操作、事件处理、多线程编程等场景,可简化代码逻辑,提高开发效率。
- 接口的默认方法和静态方法:在需要对现有接口进行扩展,同时又要保持兼容性时非常有用。
- Stream API:用于集合数据的处理,如数据过滤、映射、排序、聚合等操作。
Java 9
新特性
模块化系统(Project Jigsaw)
Java 9 引入了模块系统,将 JDK、应用程序和库分成多个模块,解决了大型项目的复杂性问题,提升了应用程序的可维护性和启动性能。使用 module-info.java
文件定义模块,支持模块之间的依赖管理和封装。
示例:
java
module com.example.myapp {
requires java.base;
exports com.example.myapp.services;
}
应用场景:拆分大型单体应用为模块化结构,更容易管理依赖关系,避免 JAR 冲突,构建更小的、定制化的运行时镜像。
JShell(交互式 REPL)
JShell 是 Java 9 提供的交互式编程工具,允许开发者快速测试代码片段,无需编写完整的类和方法。
示例:
ini
$ jshell
-> int x = 10 ;
-> x * 2
20
应用场景:学习和测试新功能或 API,快速验证算法或代码片段。
改进的流(Stream API)
Java 9 为 Stream API 添加了新方法,如 takeWhile()
、dropWhile()
、ofNullable()
、iterate()
等,使其功能更强大。
示例:
java
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class StreamExample {
public static void main(String[] args) {
List < Integer > numbers = List.of( 1, 2, 3, 4, 5, 6 );
numbers.stream().takeWhile( n -> n < 4 ).forEach( System.out::println ); // 输出 1, 2, 3
}
}
应用场景:更灵活地处理数据流,在过滤、分割数据时减少代码复杂性。
改进的接口私有方法
Java 9 允许在接口中定义私有方法,用于重用逻辑,简化默认方法的实现。
示例:
java
interface MyInterface {
default void defaultMethod ( ) {
privateMethod ( );
}
private void privateMethod ( ) {
System.out.println( "Shared logic" );
}
}
应用场景:封装接口内部逻辑,避免代码重复。
更轻量的 HTTP/2 客户端
Java 9 引入了实验性的 HTTP/2 客户端 API,用于高效处理 HTTP 请求,支持异步和 WebSocket。
示例:
java
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
public class HttpClientExample {
public static void main(String[] args) throws Exception {
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create( "https://example.com" ))
.build();
HttpResponse < String > response = client.send( request, HttpResponse.BodyHandlers.ofString() );
System.out.println( response.body() );
}
}
应用场景:RESTful API 调用,支持现代网络协议的客户端开发。
集合工厂方法
Java 9 为 List
、Set
和 Map
添加了静态工厂方法,方便地创建不可变集合。
示例:
java
import java.util.List;
import java.util.Map;
import java.util.Set;
public class CollectionExample {
public static void main(String[] args) {
List < String > list = List.of( "A", "B", "C" );
Set < String > set = Set.of( "X", "Y", "Z" );
Map < String, Integer > map = Map.of( "Key1", 1, "Key2", 2 );
}
}
应用场景 :快速创建小型集合,避免使用 Arrays.asList()
产生的副作用。
使用场景
- 模块化系统适用于大型项目的开发和维护,提高代码的可管理性和可维护性。
- JShell 适合开发者进行快速代码测试和学习。
- 改进的流和接口私有方法可用于优化代码逻辑。
- HTTP/2 客户端适用于网络请求开发。
- 集合工厂方法方便创建不可变集合。
Java 10
新特性
局部变量类型推断
Java 10 引入了局部变量类型推断,允许使用 var
关键字声明局部变量,编译器会自动推断变量类型。
示例:
java
var list = new ArrayList < String > ( ); // ArrayList<String>
var stream = list.stream(); // Stream<String>
注意事项 :var
不是关键字,而是保留字,只能用于局部变量初始化、for
循环内部索引变量和传统的 for
循环声明变量,不能用于方法参数、构造函数参数、方法返回类型、字段等。
统一的垃圾回收接口
Java 10 引入了统一的垃圾回收接口,使得新的垃圾收集器可以更方便地集成到 JDK 中。
并行全垃圾回收器 G1
Java 10 对 G1 垃圾回收器进行了改进,引入并行全垃圾回收,提高了垃圾回收效率。
使用场景
- 局部变量类型推断可简化代码,提高开发效率,但要注意避免过度使用影响代码可读性。
- 统一的垃圾回收接口和并行全垃圾回收器 G1 有助于优化内存管理和垃圾回收性能。
Java 11
新特性
新的字符串处理方法
Java 11 为 String
类增加了多个实用方法,如 isBlank()
、lines()
、strip()
、repeat(int count)
等,简化了字符串处理。
示例:
java
String str = " Hello Java 11 " ;
System.out.println( str.isBlank() ); // false
System.out.println( str.strip() ); // "Hello Java 11"
System.out.println( str.lines().count() ); // 按行分割后统计行数
System.out.println( "Java".repeat( 3 ) ); // "JavaJavaJava"
应用场景:日常字符串处理,如检查输入、去除空格等,快速生成重复的文本模板。
Lambda 表达式参数支持局部变量语法
在 Lambda 表达式中,参数支持显式使用 var
声明,并可以结合注解使用。
示例:
java
( var x, var y ) -> x + y
应用场景:增强代码可读性,特别是结合注解时更直观。
HTTP Client API 的正式引入
Java 9 中引入的实验性 HTTP/2 客户端在 Java 11 中成为正式 API,支持同步和异步请求,支持 HTTP/1.1 和 HTTP/2,内置支持 WebSocket。
示例:
java
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
public class HttpClientExample {
public static void main(String[] args) throws Exception {
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create( "https://example.com" ))
.build();
HttpResponse < String > response = client.send( request, HttpResponse.BodyHandlers.ofString() );
System.out.println( response.body() );
}
}
应用场景:RESTful API 调用,支持现代网络协议的客户端开发。
ZGC(低延迟垃圾回收器)
Java 11 引入了 ZGC,一个专为超低延迟设计的垃圾回收器,暂停时间不超过 10 毫秒,支持超大堆内存(TB 级),适用于延迟敏感的应用。
应用场景:高性能服务端应用,延迟要求严格的实时系统。
使用场景
- 新的字符串处理方法可用于日常字符串操作。
- Lambda 表达式参数支持局部变量语法可提高代码可读性。
- HTTP Client API 适用于网络请求开发。
- ZGC 适合对延迟敏感的应用。
Java 12
新特性
Switch 表达式(预览)
Java 12 引入了 Switch 表达式的预览特性,扩展的 switch
语句不仅可以作为语句,还可以作为表达式,并且可以使用简化的 "case L ->" 模式匹配语法,省去了 break
语句,避免了因少写 break
而出错。
示例:
java
int num = 2;
int result = switch (num) {
case 1, 2 -> 2;
case 3 -> 3;
default -> 0;
};
支持数字压缩格式化
Java 12 引入了数字压缩格式化功能,可以将数字按照不同的格式进行压缩显示。
Shenandoah GC:低停顿时间的 GC(预览)
Java 12 引入了 Shenandoah GC 的预览特性,这是一个低停顿时间的垃圾回收器。
使用场景
- Switch 表达式可简化代码逻辑,提高代码的可读性和可维护性。
- 数字压缩格式化可用于数字显示的优化。
- Shenandoah GC 适合对垃圾回收停顿时间有要求的应用。
Java 13
新特性
文本块的增强
Java 13 对文本块进行了增强,允许在文本块中使用转义字符,并且可以通过 s
来表示一个空格。
示例:
java
String json = """
{
"name": "Java",
"version": 13
}
""";
Switch 表达式的进一步改进
Java 13 对 Switch 表达式进行了进一步改进,使其更加完善。
使用场景
- 文本块的增强可用于处理复杂的文本内容,如 JSON、XML 等。
- Switch 表达式的改进可继续优化代码逻辑。
Java 14
新特性
模式匹配(针对 instanceof 的简化)
Java 14 引入了模式匹配,简化了 instanceof
检查和类型转换。
示例:
java
// Java 8 写法
if (obj instanceof String) {
String s = (String) obj;
System.out.println(s.toUpperCase());
}
// Java 14 写法
if (obj instanceof String s) {
System.out.println(s.toUpperCase());
}
记录类(预览)
Java 14 引入了记录类的预览特性,记录类是一种不可变类,用于封装数据,自动生成 equals()
、hashCode()
、toString()
等方法。
示例:
java
record Point(int x, int y) {}
废弃 CMS 垃圾回收器
Java 14 废弃了 CMS 垃圾回收器。
使用场景
- 模式匹配可简化代码中的类型检查和转换逻辑。
- 记录类适合用于简单的数据封装。
Java 15
新特性
文本块的正式引入
Java 15 正式引入了文本块,允许更方便地处理多行字符串,特别是处理 HTML、JSON、SQL 等文本片段。
示例:
java
String json = """
{
"name": "Java",
"version": 15
}
""";
密封类(预览)
Java 15 引入了密封类的预览特性,密封类可以限制类的继承关系,明确允许哪些类可以继承或实现。
示例:
java
public sealed class Shape permits Circle, Square {}
使用场景
- 文本块可用于处理复杂的文本内容。
- 密封类可增强代码的安全性和可维护性。
Java 16
新特性
模式匹配的增强
Java 16 对模式匹配进行了增强,使其更加完善。
记录类的正式引入
Java 16 正式引入了记录类,自动生成 equals()
、hashCode()
、toString()
等方法,简化了数据类的定义。
流的 toList()
方法
Java 16 为流添加了 toList()
方法,可直接将流转换为 List
。
示例:
java
import java.util.List;
import java.util.stream.Stream;
public class StreamToListExample {
public static void main(String[] args) {
List<Integer> list = Stream.of(1, 2, 3).toList();
}
}
使用场景
- 模式匹配和记录类可继续优化代码逻辑和数据类定义。
- 流的
toList()
方法方便流的结果收集。
Java 17
新特性
密封类的正式支持
Java 17 正式支持密封类,限制类的继承关系,增强代码安全性,避免滥用多态。
示例:
java
public sealed class Shape permits Circle, Square {}
模式匹配的进一步完善
Java 17 对模式匹配进行了进一步完善,简化 instanceof
检查和类型转换,例如增强型 switch
表达式。
ZGC/Shenandoah 垃圾收集器
Java 17 支持 ZGC(亚毫秒级停顿)和 Shenandoah GC(低延迟),适合大内存和实时应用。
使用场景
- 密封类和模式匹配可用于增强代码的安全性和简化代码逻辑。
- ZGC 和 Shenandoah GC 适合对垃圾回收性能有要求的应用。