Java 14 新特性详解与实践

Java 14 新特性详解与实践

Java 14 于 2020年3月17日正式发布,是一个非LTS版本。本文档将详细介绍 Java 14 中引入的主要新特性和改进。

语言特性

1. Switch 表达式 (正式版本)

Switch 表达式在 Java 12 和 13 中作为预览特性存在,在 Java 14 中正式成为标准特性。

基本语法
arduino 复制代码
// 传统 switch 语句
String result;
switch (day) {
    case MONDAY:
    case FRIDAY:
    case SUNDAY:
        result = "Meh";
        break;
    case TUESDAY:
        result = "Tiring";
        break;
    case THURSDAY:
    case SATURDAY:
        result = "Nice";
        break;
    case WEDNESDAY:
        result = "Hump day";
        break;
    default:
        throw new IllegalStateException("Invalid day: " + day);
}

// 新的 switch 表达式
String result = switch (day) {
    case MONDAY, FRIDAY, SUNDAY -> "Meh";
    case TUESDAY -> "Tiring";
    case THURSDAY, SATURDAY -> "Nice";
    case WEDNESDAY -> "Hump day";
};
yield 关键字
csharp 复制代码
String result = switch (day) {
    case MONDAY -> {
        System.out.println("Monday blues");
        yield "Meh";
    }
    case TUESDAY -> {
        System.out.println("Tuesday troubles");
        yield "Tiring";
    }
    default -> "Other day";
};

2. 有用的 NullPointerException

增强了 NullPointerException 的错误信息,精确指出哪个变量为 null。

示例
typescript 复制代码
public class HelpfulNPE {
    static class Person {
        String name;
        Address address;
    }

    static class Address {
        String city;
    }

    public static void main(String[] args) {
        Person person = new Person();
        // 这将抛出更详细的 NPE 信息
        String city = person.address.city;
    }
}

错误信息变化:

php 复制代码
// Java 13 及之前
Exception in thread "main" java.lang.NullPointerException
    at HelpfulNPE.main(HelpfulNPE.java:15)

// Java 14
Exception in thread "main" java.lang.NullPointerException:
    Cannot read field "city" because "person.address" is null
    at HelpfulNPE.main(HelpfulNPE.java:15)

3. 记录类型 (预览特性)

Records 是一种新的类声明形式,用于创建不可变的数据载体类。

基本语法
arduino 复制代码
// 传统方式
public class PersonOld {
    private final String name;
    private final int age;

    public PersonOld(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String name() { return name; }
    public int age() { return age; }

    @Override
    public boolean equals(Object o) {
        // 标准 equals 实现
    }

    @Override
    public int hashCode() {
        // 标准 hashCode 实现
    }

    @Override
    public String toString() {
        // 标准 toString 实现
    }
}

// 使用 Record
public record Person(String name, int age) {}
Record 特性
csharp 复制代码
public record Point(int x, int y) {
    // 紧凑构造器
    public Point {
        if (x < 0 || y < 0) {
            throw new IllegalArgumentException("坐标不能为负数");
        }
    }

    // 静态方法
    public static Point origin() {
        return new Point(0, 0);
    }

    // 实例方法
    public double distanceFromOrigin() {
        return Math.sqrt(x * x + y * y);
    }
}

// 使用示例
Point p1 = new Point(3, 4);
Point p2 = new Point(3, 4);

System.out.println(p1.x());                    // 3
System.out.println(p1.y());                    // 4
System.out.println(p1.equals(p2));             // true
System.out.println(p1.toString());             // Point[x=3, y=4]
System.out.println(p1.distanceFromOrigin());   // 5.0

4. 模式匹配 instanceof (预览特性)

简化了 instanceof 检查后的类型转换。

传统方式 vs 新方式
typescript 复制代码
// 传统方式
if (obj instanceof String) {
    String str = (String) obj;
    System.out.println(str.length());
}

// 模式匹配 instanceof
if (obj instanceof String str) {
    System.out.println(str.length());
}

// 更复杂的示例
public String formatValue(Object obj) {
    if (obj instanceof Integer i) {
        return String.format("整数: %d", i);
    } else if (obj instanceof String s && s.length() > 10) {
        return String.format("长字符串: %s", s.substring(0, 10) + "...");
    } else if (obj instanceof String s) {
        return String.format("字符串: %s", s);
    } else {
        return "未知类型";
    }
}

1. String API 增强

1.1 新增方法
ini 复制代码
// String.formatted() - 格式化字符串
String name = "Java";
int version = 14;
String message = "Hello, %s %d!".formatted(name, version);
System.out.println(message); // Hello, Java 14!

// String.stripIndent() - 移除缩进
String multiline = """
    第一行
        第二行
            第三行
    """;
String stripped = multiline.stripIndent();
System.out.println(stripped);
/*
第一行
    第二行
        第三行
*/

// String.translateEscapes() - 转义字符处理
String escaped = "Hello\nWorld\t!";
String translated = escaped.translateEscapes();
System.out.println(translated); // Hello[换行]World[制表符]!

最佳实践

1.1 Switch 表达式
typescript 复制代码
// 好的实践
public String processStatus(Status status) {
    return switch (status) {
        case PENDING -> "处理中";
        case APPROVED -> "已批准";
        case REJECTED -> "已拒绝";
        case CANCELLED -> "已取消";
    }; // 编译器确保所有情况都被覆盖
}

// 避免混用新旧语法
public String processStatusBad(Status status) {
    switch (status) {
        case PENDING -> "处理中";    // 新语法
        case APPROVED:              // 旧语法,不推荐混用
            return "已批准";
        default -> "未知状态";
    }
}
1.2 Record 使用
csharp 复制代码
// 好的实践 - 不可变数据载体
public record Person(String name, int age) {
    public Person {
        if (age < 0) throw new IllegalArgumentException("年龄不能为负数");
        if (name == null || name.trim().isEmpty()) {
            throw new IllegalArgumentException("姓名不能为空");
        }
    }
}

// 避免 - 复杂业务逻辑类
// Record 不适合包含大量业务逻辑的类
1.3 模式匹配 instanceof
typescript 复制代码
// 好的实践
public double calculateArea(Shape shape) {
    if (shape instanceof Circle c) {
        return Math.PI * c.radius() * c.radius();
    } else if (shape instanceof Rectangle r) {
        return r.width() * r.height();
    } else if (shape instanceof Triangle t) {
        return 0.5 * t.base() * t.height();
    }
    throw new IllegalArgumentException("未知形状");
}

// 避免过于复杂的条件
public String formatComplexCondition(Object obj) {
    // 避免这样的复杂条件,考虑重构
    if (obj instanceof String s && s.length() > 10 && s.contains("important") && !s.startsWith("test")) {
        return "复杂字符串处理";
    }
    return "简单处理";
}

总结

Java 14 虽然是一个非 LTS 版本,但引入了多个重要特性:

正式特性

  1. Switch 表达式 - 提供了更简洁、安全的分支处理方式
  2. 有用的 NullPointerException - 极大改善了调试体验

预览特性

  1. Record 类型 - 简化不可变数据类的创建
  2. 模式匹配 instanceof - 减少样板代码
相关推荐
腻害兔1 小时前
【若依项目-产品经理视角】深度拆解 RuoYi-Vue-Pro 商城模块:从商品管理到交易引擎,50 张表撑起一整套电商系统
java·大数据·vue.js·产品经理·ai编程
GetcharZp2 小时前
抛弃低效SSH!这套Ansible+Web可视化神器,让你天天准点下班!
后端
码智社2 小时前
AES加密原理详解及Java实现加解密实战
java·开发语言
触底反弹3 小时前
🔥 2026 大模型选择指南:别再只看 Benchmark 了,这些维度才是关键!
人工智能·面试
萧瑟余晖3 小时前
JDK 26 新特性详解
java·开发语言
马优晨4 小时前
Freemarker 完整讲解(后端 Java 模板引擎)
java·开发语言·freemarker·freemarker 完整讲解·freemarker模板引擎
醇氧4 小时前
CountDownLatch / CyclicBarrier / Semaphore 面试高频问答清单
前端·面试·职场和发展
weixin_446260855 小时前
HACO:面向动态部署环境的对冲式智能计算可靠多智能体调度框架
后端·python·flask
ttwuai7 小时前
Cursor 生成 CRUD 后,Go 后台接口别只测 200:JWT、RBAC 和 tenant_id 怎么验
开发语言·后端·golang