JDK 11 新特性详解

📅 发布时间:2026/7/16 0:10:29 👁️ 浏览次数:
JDK 11 新特性详解
JDK 11 新特性详解JDK 11 于2018年9月25日正式发布,是继 JDK 8 之后的第二个长期支持(LTS)版本,也是 Oracle 改变 JDK 许可模式后的第一个版本。JDK 11 包含大量重要特性:Lambda 参数 var、String 新方法、正式 HTTP Client API、Flight Recorder、ZGC、Epsilon GC、单文件源码启动、TLS 1.3 支持等,是一次内容极其丰富的 LTS 升级。目录Lambda 参数 var 注解String 新方法文件读写新方法集合新方法Optional 新方法HTTP Client API(正式)Launch Single-File Source CodeFlight Recorder(JFR)ZGC(实验性)Epsilon GCShenandoah GC(实验性)TLS 1.3 支持Unicode 10 支持移除 Java EE 和 CORBA 模块Nashorn JavaScript 引擎废弃动态 CDS 归档其他重要特性JDK 11 特性总览表1. Lambda 参数 var 注解1.1 概述JDK 11 允许在 Lambda 表达式的参数上使用var关键字(JEP 323),主要目的是让开发者能够为 Lambda 参数添加注解。核心规则:所有 Lambda 参数必须同时使用var或同时不使用不能混合使用var和显式类型var在 Lambda 中仅用于注解,类型推断行为不变1.2 代码案例// ============ 1. Lambda 参数使用 var ============// JDK 10 及之前:无法为 Lambda 参数添加注解// (s) - s.length() // 无法添加 @NonNull 等注解// JDK 11:可以为 Lambda 参数添加注解(@NonNullvars)-s.length()// 多个参数(varx,vary)-x+y// ============ 2. 注解示例 ============importjava.lang.annotation.*;@Target(ElementType.TYPE_USE)@Retention(RetentionPolicy.RUNTIME)@interfaceNonNull{}@Target(ElementType.TYPE_USE)@Retention(RetentionPolicy.RUNTIME)@interfaceEmail{}// 使用注解ListStringnames=List.of("Alice","Bob","Charlie");// 为 Lambda 参数添加注解names.stream().map((@NonNullvarname)-name.toUpperCase()).forEach(System.out::println);// 多个参数names.stream().sorted((@NonNullvara,@NonNullvarb)-a.compareTo(b)).forEach(System.out::println);// ============ 3. 规则:必须统一使用 var ============// ✅ 正确:全部使用 var(varx,vary)-x+y// ✅ 正确:全部不使用 var(x,y)-x+y// ❌ 错误:混合使用// (var x, y) - x + y // 编译报错// (var x, String y) - x + y // 编译报错// ============ 4. 实际应用场景 ============// 静态分析工具(如 Checker Framework)ListStringinputs=List.of("hello","world");ListIntegerlengths=inputs.stream().map((@NonNullvars)-s.length()).collect(Collectors.toList());// 自定义验证inputs.stream().filter((@Emailvaremail)-email.contains("@")).forEach(System.out::println);// ============ 5. 对比方法引用 ============// 当不需要注解时,方法引用更简洁names.stream().map(String::toUpperCase)// 推荐.forEach(System.out::println);// 需要注解时才使用 varnames.stream().map((@NonNullvars)-s.toUpperCase()).forEach(System.out::println);2. String 新方法2.1 概述JDK 11 为String类新增了多个实用方法(JEP 329 的一部分),大幅增强了字符串处理能力。新增方法一览:方法说明isBlank()判断是否为空或只包含空白字符lines()按行分割为 Streamstrip()去除首尾空白(支持 Unicode)stripLeading()去除首部空白stripTrailing()去除尾部空白repeat(int)重复字符串指定次数2.2 代码案例// ============ 1. isBlank() — 判断是否为空或只包含空白 ============"".isBlank();// true" ".isBlank();// true(空格)"\t\n".isBlank();// true(制表符+换行)" a ".isBlank();// false"hello".isBlank();// false// 对比 isEmpty()"".isEmpty();// true" ".isEmpty();// false(有空格,不为空)" ".isBlank();// true(但全是空白)// 实际应用:验证用户输入StringuserInput=" ";if(userInput.isBlank()){System.out.println("输入不能为空或只包含空白");}// ============ 2. lines() — 按行分割为 Stream ============Stringmultiline="line1\nline2\nline3\nline4";// 返回 StreamStringListStringlines=multiline.lines().collect(Collectors.toList());// ["line1", "line2", "line3", "line4"]// 支持 \n, \r, \r\nStringmixed="line1\nline2\rline3\r\nline4";mixed.lines().forEach(System.out::println);// 实际应用:处理多行配置Stringconfig=""" server.host=localhost server.port=8080 server.timeout=30 """;MapString,StringconfigMap=config.lines().filter(line-!line.isBlank()).map(line-line.split("=",2)).filter(parts-parts.length==2).collect(Collectors.toMap(parts-parts[0].trim(),parts-parts[1].trim()));// {server.host=localhost, server.port=8080, server.timeout=30}// 实际应用:过滤空行Stringtext="Hello\n\nWorld\n\nJava";ListStringnonEmptyLines=text.lines().filter(line-!line.isBlank()).collect(Collectors.toList());// ["Hello", "World", "Java"]// ============ 3. strip() — 去除首尾空白(Unicode 感知) ============// strip() 去除所有 Unicode 空白字符" hello ".strip();// "hello""\t hello \n".strip();// "hello""\u2000hello\u2000".strip();// "hello"(Unicode 空白)// stripLeading() — 只去除首部" hello ".stripLeading();// "hello "// stripTrailing() — 只去除尾部" hello ".stripTrailing();// " hello"// 对比 trim()// trim() 只去除 ASCII 空白(code = U+0020)// strip() 去除所有 Unicode 空白(Character.isWhitespace)StringunicodeSpace="\u2000hello\u2000";// Unicode 空白unicodeSpace.trim();// "\u2000hello\u2000"(不去除,不是 ASCII 空白)unicodeSpace.strip();// "hello"(去除,是 Unicode 空白)// 实际应用:清理用户输入StringrawInput=" \t Alice \n";StringcleanInput=rawInput.strip();// "Alice"// ============ 4. repeat(int) — 重复字符串 ============"ha".repeat(3);// "hahaha""-".repeat(10);// "----------""abc".repeat(0);// ""(重复0次为空)"hello".repeat(1);// "hello"(重复1次不变)// 实际应用:生成表格分隔线intwidth=50;Stringseparator="=".repeat(width);// "=================================================="// 实际应用:生成缩进intindent=4;Stringindentation=" ".repeat(indent);// " "// 实际应用:生成进度条intprogress=7;inttotal=10;Stringbar="█".repeat(progress)+"░".repeat(total-progress);// "███████░░░"// 实际应用:填充字符串到固定长度StringpadRight(Strings,intlength){returns+" ".repeat(Math.max(0,length-s.length()));}StringpadLeft(Strings,intlength){return" ".repeat(Math.max(0,length-s.length()))+s;}// ============ 5. 综合应用 ============// 处理 CSV 文件Stringcsv=""" name,age,city Alice,25,Beijing Bob,30,Shanghai Charlie,20,Guangzhou """;ListMapString,Stringrecords=csv.lines().filter(line-!line.isBlank())// 过滤空行.skip(1)// 跳过表头.map(line-line.split(",")).filter(parts-parts.length==3).map(parts-Map.of("name",parts[0].strip(),