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 - 减少样板代码
相关推荐
Doris_20232 小时前
Python 模式匹配match case
前端·后端·python
ytadpole2 小时前
揭秘XXL-JOB:Bean、GLUE 与脚本模式的底层奥秘
java·后端
计算机毕业设计木哥2 小时前
计算机毕设选题推荐:基于Java+SpringBoot物品租赁管理系统【源码+文档+调试】
java·vue.js·spring boot·mysql·spark·毕业设计·课程设计
青衫客362 小时前
Spring异步编程- 浅谈 Reactor 核心操作符
java·spring·响应式编程
shark_chili2 小时前
计算机磁盘的奥秘:从硬件构造到操作系统管理
后端
Seven972 小时前
剑指offer-30、连续⼦数组的最⼤和
java
BenChuat2 小时前
Java常见排序算法实现
java·算法·排序算法
熙客2 小时前
SpringCloud概述
java·spring cloud·微服务
这里有鱼汤2 小时前
Python量化实盘踩坑指南:分钟K线没处理好,小心直接亏钱!
后端·python·程序员