JDK 12 新特性详解
JDK 12 于2019年3月19日正式发布,是一个非 LTS(Non-LTS)版本。该版本引入了多个重要的语言特性预览(Switch 表达式、Pattern Matching),以及多项 JVM 和 GC 优化(G1 增强、ZGC 改进、Shenandoah GC 正式纳入)。JDK 12 为后续 LTS 版本(JDK 17)的多项核心特性奠定了基础。
目录
- Switch 表达式(Preview)
- Pattern Matching for instanceof(Preview)
- String 新方法:transform()
- NumberFormat 增强:紧凑数字格式
- Files.mismatch() 方法
- JVM Constants API
- Shenandoah GC(实验性)
- G1 GC 多项增强
- ZGC 未提交内存回收(实验性)
- 默认 CDS 归档
- Microbenchmark Suite
- AArch64 统一端口
- JDK 12 特性总览表
- 总结
1. Switch 表达式(Preview)
1.1 概述
JEP 325 引入了Switch 表达式作为预览特性。Switch 表达式支持箭头语法(->),无需break语句,并且可以作为表达式返回值。这是 Java 语言演进中最受期待的特性之一,最终在 JDK 14 正式定稿。
核心改进:
- 箭头标签(
->):无需break,不会穿透(fall-through) - 作为表达式使用:可以返回值给变量
yield关键字:在代码块中返回值
1.2 代码案例
// ============ 1. 传统 switch vs Switch 表达式 ============// 传统 switch(需要 break,容易遗漏)Stringday="MONDAY";Stringtype;switch(day){case"MONDAY":case"TUESDAY":case"WEDNESDAY":case"THURSDAY":case"FRIDAY":type="工作日";break;case"SATURDAY":case"SUNDAY":type="周末";break;default:type="未知";}// Switch 表达式(箭头语法,无需 break)Stringtype2=switch(day){case"MONDAY","TUESDAY","WEDNESDAY","THURSDAY","FRIDAY"->"工作日";case"SATURDAY","SUNDAY"->"周末";default->"未知";};System.out.println(type2);// "工作日"// ============ 2. 多值匹配 ============intnumLetters=switch(day){case"MONDAY","FRIDAY","SUNDAY"->6;case"TUESDAY"->7;case"THURSDAY","SATURDAY"->8;case"WEDNESDAY"->9;default->thrownewIllegalStateException("Invalid day: "+day);};System.out.println(numLetters);// 6// ============ 3. yield 关键字(代码块返回值) ============// 当 case 分支需要多行逻辑时,使用 yield 返回值Stringresult=switch(day){case"MONDAY"->{System.out.println("新的一周开始了");yield"工作日";}case"FRIDAY"->{System.out.println("快到周末了");yield"工作日";}case"SATURDAY","SUNDAY"->{System.out.println("享受周末");yield"周末";}default->{yield"未知";}};// ============ 4. 结合枚举使用 ============enumStatus{PENDING,APPROVED,REJECTED,COMPLETED}StringdescribeStatus(Statusstatus){returnswitch(status){casePENDING->"待审批";caseAPPROVED->"已批准";caseREJECTED->"已拒绝";caseCOMPLETED->"已完成";};// 编译器知道所有枚举值已覆盖,无需 default}System.out.println(describeStatus(Status.APPROVED));// "已批准"// ============ 5. 结合模式匹配(Preview) ============Objectobj="Hello JDK 12";Stringdescription=switch(obj){caseIntegeri->"整数: "+i;caseStrings->"字符串: "+s;caseLongl->"长整数: "+l;casenull->"空值";default->"未知类型: "+obj.getClass().getSimpleName();};System.out.println(description);// "字符串: Hello JDK 12"// ============ 6. 在表达式中使用 ============// 直接作为方法参数System.out.println(switch(day){case"MONDAY"->"周一";case"TUESDAY"->"周二";case"WEDNESDAY"->"周三";case"THURSDAY"->"周四";case"FRIDAY"->"周五";default->"其他";});// 用于三元表达式intx=5;Stringparity=switch(x%2){case0->"偶数";case1->"奇数";default->"未知";};// ============ 7. 传统 switch 的穿透问题对比 ============// 传统 switch 容易遗漏 break 导致穿透Stringfruit="apple";switch(fruit){case"apple":System.out.println("苹果");// 忘记 break,会穿透到下一个 casecase"banana":System.out.println("香蕉");break;case"orange":System.out.println("橙子");break;}// 输出:苹果 香蕉(穿透了!)// Switch 表达式不会穿透switch(fruit){case"apple"->System.out.println("苹果");case"banana"->System.out.println("香蕉");case"orange"->System.out.println("橙子");}// 输出:苹果(不会穿透)2. Pattern Matching for instanceof(Preview)
2.1 概述
JEP 305 引入了instanceof 模式匹配作为预览特性。当instanceof检测成功后,自动将对象转换为指定类型并绑定到一个新变量,省去显式类型转换。该特性最终在 JDK 16 正式定稿。
2.2 代码案例
// ============ 1. 传统 instanceof vs 模式匹配 ============Objectobj="Hello JDK 12";// 传统写法:先判断,再强制转换if(objinstanceofString){Stringstr=(String)obj;System.out.println(str.length());}// 模式匹配写法:判断的同时绑定变量if(objinstanceofStringstr){System.out.println(str.length());// 直接使用 str}// ============ 2. 简化条件分支 ============// 传统写法if(objinstanceofInteger){intvalue=(Integer)obj;System.out.println("Integer: "+value);}elseif(objinstanceofLong){longvalue=(Long)obj;System.out.println("Long: "+value);}elseif(objinstanceofString){Stringvalue=(String)obj;System.out.println("String: "+value);}elseif(obj==null){System.out.println("null");}else{System.out.println("Unknown: "+obj.getClass());}// 模式匹配写法if(objinstanceofIntegeri){System.out.println("Integer: "+i);}elseif(objinstanceofLongl){System.out.println("Long: "+l);}elseif(objinstanceofStrings){System.out.println("String: "+s);}elseif(obj==null){System.out.println("null");}else{System.out.println("Unknown: "+obj.getClass());}// ============ 3. 结合逻辑表达式 ============// instanceof 模式匹配可以与 && 结合// 变量只在条件为 true 时可用if(objinstanceofStrings&&s.length()>5){System.out.println("长字符串: "+s);}// ============ 4. 在 equals 方法中使用 ============classPoint{privatefinalintx;privatefinalinty;Point(intx,inty){this.x=x;this.y=y;}// 传统 equals@Overridepublicbooleanequals(Objectobj){if(this==obj)returntrue;if(!(objinstanceofPoint))returnfalse;Pointother=(Point)obj;returnthis.x==other.x&&this.y==other.y;}// 模式匹配简化 equalspublicbooleanequalsV2(Objectobj){if(this==