作者:Grey
原文地址:Java SE 14 新增特性
源仓库: Github:java_new_features
镜像仓库: GitCode:java_new_features
switch 表达式在 Java SE 12 和 Java SE 13 中一直是预览功能,现在在 Java SE 14 中成为正式功能
Java SE 12中为 switch 表达式引入了 lambda 语法,从而允许匹配多个 case 标签。
Java SE 13,引入了 yield 语句用于从表达式中返回值。
代码见
package git.snippets.jdk14; /** * switch 增强 * * @author <a href="mailto:[email protected]">Grey</a> * @date 2021/11/29 * @since 14 */ public class SwitchInJdk14 { public static void main(String[] args) { test("apple"); test2("june"); System.out.println(test3("apple")); System.out.println(test3("abc")); } // 在jdk12是预览特性,在14正式引入 static void test(String c) { switch (c) { case "apple", "Apple" -> System.out.println("苹果"); case "banana", "Banana" -> System.out.println("香蕉"); } } static void test2(String day) { String season = switch (day) { case "march", "april", "may" -> "春天"; case "june", "july", "august" -> "夏天"; case "september", "october", "november" -> "秋天"; case "december", "january", "february" -> "冬天"; default -> { throw new RuntimeException("day error"); } }; System.out.println("当前季节是:" + season); } private static String test3(String c) { return switch (c) { case "apple", "Apple": yield "苹果"; case "banana": yield "香蕉"; default: yield "无法识别"; }; } }
输出结果
苹果 当前季节是:夏天 苹果 无法识别
一个 instanceof 条件检查后一般会有一个类型转换。
在 Java SE 14 之前
// Before Java 14: if (obj instanceof H) { H jd1 = (H) obj; jd1.setId(1); }
在 Java SE 14 中,可以简化为
// Java 14+ if (obj instanceof H jd2) { jd2.setId(1); }
这个功能在 Java SE 14 中是预览功能。在 Java SE 14 环境下,需要启用 --enable-preview 才能运行代码。
Records 是存储纯数据的数据类。使用 Records 是为了快速创建简单而简洁的类(不含模板代码)。
通常,在 Java 中,一个类需要你实现equals()
、hashCode()
、getters
和setters
方法。虽然有些 IDE 支持自动生成这样的类,但代码仍然很冗长。有了 Records,你可以简单地定义一个不包括上述方法的类,示例代码如下
package git.snippets.jdk14; /** * @author <a href="mailto:[email protected]">Grey</a> * @date 2021/11/29 * @since 14 */ public record Author(String name, String topic) { } // 或者 //record Author(){}
使用这个 record ,
package git.snippets.jdk14; /** * Records在jdk14是预览功能 * 到jdk16正式发布 * * @author <a href="mailto:[email protected]">Grey</a> * @date 2021/11/29 * @since */ public class RecordsTest { // record 是一种全新的类型,它本质上是一个 final 类, // 同时所有的属性都是 final 修饰,它会自动编译出 public get hashcode 、equals、toString 等方法,减少了代码编写量。 public static void main(String[] args) { Author c1 = new Author("A", "B"); Author c3 = new Author("A", "B"); Author c2 = new Author("A", "B"); System.out.println(c1); System.out.println(c2); System.out.println(c1 == c3); } }
record 中可以定义方法和成员变量,例如
record Author (int id, String name, String topic) { static int followers; public static String followerCount() { return "Followers are "+ followers; } public String description(){ return "Author "+ name + " writes on "+ topic; } public Author{ if (id < 0) { throw new IllegalArgumentException( "id must be greater than 0."); } } }
同时,record 也可以实现接口
record Author(String name, String topic) implements Information { public String getFullName() { return "Author "+ name + " writes on " + topic; } } interface Information { String getFullName(); }
支持多个构造函数
record Author(String name, String topic) { public Author() { this("NA", "NA"); } public Author(String name) { this(name, "NA"); } }
它本质上是一个 final 类,同时所有的属性都是 final 修饰,它会自动编译出 public get hashcode 、equals、toString 等方法,减少了代码编写量。
使用javap
查看 record 的 class 文件,可以得到验证
C:\Users\Young\Downloads>javac Author.java && javap Author Compiled from "Author.java" public final class Author extends java.lang.Record implements Information { public Author(); public Author(java.lang.String); public Author(java.lang.String, java.lang.String); public java.lang.String getFullName(); public final java.lang.String toString(); public final int hashCode(); public final boolean equals(java.lang.Object); public java.lang.String name(); public java.lang.String topic(); }
Records 到 Java SE 16 正式发布,在 Java SE 14 中是预览功能。
如下代码:
public class NullPointerTest { public static void main(String[] args) { String s = null; System.out.println(s.isEmpty()); } }
在 Java SE 14 之前,报错信息如下
Exception in thread "main" java.lang.NullPointerException at NullPointerTest.main(NullPointerTest.java:5)
在 Java SE 14 后,优化了 NPE 的报错提示,在 Java SE 14 下执行,报错信息如下
Exception in thread "main" java.lang.NullPointerException: Cannot invoke "String.isEmpty()" because "<local1>" is null at NullPointerTest.main(NullPointerTest.java:5)
会提示出具体哪个对象是 null。
文本块是在 Java SE 13 中作为预览功能引入的,目的是允许轻松创建多行字符串。这个功能在创建 HTML 和 JSON 或 SQL 查询字符串方面很有用。
在Java SE 14 中,Text Blocks 仍处于预览阶段,并增加了一些新功能,增加了
\
结尾不换行
\s
表示一个空格
示例代码
package git.snippets.jdk14; /** * Block功能的二次预览 * 到jdk15中正式发布 * * @author <a href="mailto:[email protected]">Grey</a> * @date 2021/11/29 * @since 14 */ public class BlockInJdk14 { public static void main(String[] args) { String content = """ { "hello": 1,\ "world": 2, "hello world": "1\s2", } """; System.out.println(content); } }
输出结果如下
{ "hello": 1, "world": 2, "hello world": "1 2", }
文本块功能在 Java SE 15 中正式启用。
Java SE 7及以后各版本新增特性
JDK 14 Release Notes
Java 14 Features
Java 14 新功能介绍