Skip to content

JDK 12-17 特性详解

JDK 12到JDK 17是Java语言发展的重要版本,引入了许多新特性和改进。本文将详细介绍这些版本的主要特性,并通过示例代码来说明其用法。

JDK 12 特性

1. Switch表达式(预览特性)

JDK 12引入了Switch表达式的预览特性,允许Switch语句返回值。

示例

java
// 传统Switch语句
String result;
int day = 3;
switch (day) {
    case 1:
        result = "Monday";
        break;
    case 2:
        result = "Tuesday";
        break;
    case 3:
        result = "Wednesday";
        break;
    default:
        result = "Unknown";
        break;
}
System.out.println(result);

// 使用Switch表达式
String result2 = switch (day) {
    case 1 -> "Monday";
    case 2 -> "Tuesday";
    case 3 -> "Wednesday";
    default -> "Unknown";
};
System.out.println(result2);

// 多行语句
String result3 = switch (day) {
    case 1 -> {
        System.out.println("Processing Monday");
        yield "Monday";
    }
    case 2 -> "Tuesday";
    case 3 -> "Wednesday";
    default -> "Unknown";
};
System.out.println(result3);

2. 数字格式化(CompactNumberFormat)

JDK 12引入了CompactNumberFormat类,用于格式化数字为紧凑形式。

示例

java
import java.text.CompactNumberFormat;
import java.util.Locale;

public class CompactNumberFormatExample {
    public static void main(String[] args) {
        // 创建美国英语的CompactNumberFormat
        CompactNumberFormat format = CompactNumberFormat.getInstance(
            Locale.US, CompactNumberFormat.Style.SHORT
        );
        
        System.out.println(format.format(1000)); // 输出: 1K
        System.out.println(format.format(1500)); // 输出: 1.5K
        System.out.println(format.format(1000000)); // 输出: 1M
        System.out.println(format.format(1500000)); // 输出: 1.5M
        
        // 创建中文的CompactNumberFormat
        CompactNumberFormat formatCN = CompactNumberFormat.getInstance(
            Locale.CHINA, CompactNumberFormat.Style.SHORT
        );
        
        System.out.println(formatCN.format(1000)); // 输出: 1千
        System.out.println(formatCN.format(1500)); // 输出: 1.5千
        System.out.println(formatCN.format(1000000)); // 输出: 100万
    }
}

3. JVM常量API

JDK 12引入了JVM常量API,用于处理常量池中的常量。

4. 其他改进

  • Shenandoah垃圾收集器:作为实验性特性引入,目标是低延迟垃圾收集
  • 微基准测试框架:引入JMH(Java Microbenchmark Harness)作为标准工具

JDK 13 特性

1. Switch表达式(第二个预览版)

JDK 13继续改进Switch表达式,添加了yield关键字。

2. 文本块(预览特性)

JDK 13引入了文本块的预览特性,允许使用三引号(""")创建多行字符串。

示例

java
// 传统多行字符串
String html = "<html>" +
              "<body>" +
              "<p>Hello, World!</p>" +
              "</body>" +
              "</html>";

// 使用文本块
String htmlBlock = """
    <html>
    <body>
    <p>Hello, World!</p>
    </body>
    </html>
    """;

// 文本块中的表达式
String name = "World";
String greeting = """
    Hello, %s!
    How are you today?
    """.formatted(name);
System.out.println(greeting);

3. 动态CDS档案

JDK 13引入了动态CDS(Class-Data Sharing)档案,允许在应用程序运行时动态创建CDS档案。

JDK 14 特性

1. Switch表达式(正式版)

JDK 14将Switch表达式从预览特性提升为正式特性。

2. 文本块(第二个预览版)

JDK 14继续改进文本块,添加了转义序列支持。

3. 记录(预览特性)

JDK 14引入了记录(Record)的预览特性,用于创建不可变的数据类。

示例

java
// 传统数据类
class Point {
    private final int x;
    private final int y;
    
    public Point(int x, int y) {
        this.x = x;
        this.y = y;
    }
    
    public int getX() {
        return x;
    }
    
    public int getY() {
        return y;
    }
    
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Point point = (Point) o;
        return x == point.x && y == point.y;
    }
    
    @Override
    public int hashCode() {
        return Objects.hash(x, y);
    }
    
    @Override
    public String toString() {
        return "Point{x=" + x + ", y=" + y + "}";
    }
}

// 使用记录
record PointRecord(int x, int y) {
    // 可以添加自定义方法
    public PointRecord move(int dx, int dy) {
        return new PointRecord(x + dx, y + dy);
    }
}

// 使用记录
PointRecord point = new PointRecord(10, 20);
System.out.println(point); // 输出: PointRecord[x=10, y=20]
System.out.println(point.x()); // 输出: 10
System.out.println(point.y()); // 输出: 20

PointRecord moved = point.move(5, 5);
System.out.println(moved); // 输出: PointRecord[x=15, y=25]

4. 其他改进

  • NullPointerException增强:提供更详细的错误信息,指示哪个变量为null
  • G1垃圾收集器改进:引入NUMA-aware内存分配和并发标记开始时间的自适应调整

JDK 15 特性

1. 文本块(正式版)

JDK 15将文本块从预览特性提升为正式特性。

2. 记录(第二个预览版)

JDK 15继续改进记录,添加了密封类的支持。

3. 密封类(预览特性)

JDK 15引入了密封类(Sealed Classes)的预览特性,限制类的继承。

示例

java
// 密封类
sealed class Shape permits Circle, Rectangle, Triangle {
    // 共同方法
}

final class Circle extends Shape {
    private final double radius;
    
    public Circle(double radius) {
        this.radius = radius;
    }
    
    public double area() {
        return Math.PI * radius * radius;
    }
}

final class Rectangle extends Shape {
    private final double width;
    private final double height;
    
    public Rectangle(double width, double height) {
        this.width = width;
        this.height = height;
    }
    
    public double area() {
        return width * height;
    }
}

final class Triangle extends Shape {
    private final double base;
    private final double height;
    
    public Triangle(double base, double height) {
        this.base = base;
        this.height = height;
    }
    
    public double area() {
        return 0.5 * base * height;
    }
}

// 使用密封类
public class SealedClassesExample {
    public static void main(String[] args) {
        Shape[] shapes = {
            new Circle(5),
            new Rectangle(4, 5),
            new Triangle(3, 6)
        };
        
        for (Shape shape : shapes) {
            System.out.println("Area: " + getArea(shape));
        }
    }
    
    public static double getArea(Shape shape) {
        // 可以使用模式匹配
        if (shape instanceof Circle circle) {
            return circle.area();
        } else if (shape instanceof Rectangle rectangle) {
            return rectangle.area();
        } else if (shape instanceof Triangle triangle) {
            return triangle.area();
        }
        return 0;
    }
}

4. 其他改进

  • ZGC垃圾收集器:从实验性特性提升为生产特性
  • Shenandoah垃圾收集器:从实验性特性提升为生产特性

JDK 16 特性

1. 记录(正式版)

JDK 16将记录从预览特性提升为正式特性。

2. 密封类(第二个预览版)

JDK 16继续改进密封类,添加了对接口的支持。

3. 模式匹配 for instanceof(正式版)

JDK 16将模式匹配 for instanceof从预览特性提升为正式特性。

示例

java
// 传统方式
if (obj instanceof String) {
    String s = (String) obj;
    System.out.println(s.length());
}

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

// 与其他条件结合
if (obj instanceof String s && s.length() > 0) {
    System.out.println(s.toUpperCase());
}

// 在switch中使用
switch (obj) {
    case Integer i -> System.out.println("Integer: " + i);
    case String s -> System.out.println("String: " + s);
    default -> System.out.println("Other type");
}

4. Vector API(孵化器)

JDK 16引入了Vector API的孵化器版本,用于高性能的向量计算。

5. 其他改进

  • Unix域套接字通道:添加了对Unix域套接字的支持
  • 弹性元空间:自动调整元空间大小,减少内存占用

JDK 17 特性

1. 密封类(正式版)

JDK 17将密封类从预览特性提升为正式特性。

2. 模式匹配 for switch(预览特性)

JDK 17引入了模式匹配 for switch的预览特性。

示例

java
// 使用模式匹配 for switch
Object obj = "Hello";
String result = switch (obj) {
    case Integer i -> "Integer: " + i;
    case String s -> "String: " + s;
    case Double d -> "Double: " + d;
    default -> "Other type";
};
System.out.println(result);

// 带有null处理
Object obj2 = null;
String result2 = switch (obj2) {
    case null -> "null";
    case Integer i -> "Integer: " + i;
    case String s -> "String: " + s;
    default -> "Other type";
};
System.out.println(result2);

// 带有守卫条件
Object obj3 = 42;
String result3 = switch (obj3) {
    case Integer i when i > 0 -> "Positive integer: " + i;
    case Integer i -> "Non-positive integer: " + i;
    case String s -> "String: " + s;
    default -> "Other type";
};
System.out.println(result3);

3. 移除和废弃的特性

  • 移除:实验性的AOT和JIT编译器
  • 废弃:Applet API、Security Manager

4. 其他改进

  • 增强的伪随机数生成器:添加了新的随机数生成器接口和实现
  • 上下文特定的反序列化过滤器:提供更灵活的反序列化控制

总结

JDK 12-17引入了许多重要的特性和改进,包括:

  • JDK 12:Switch表达式(预览)、数字格式化、JVM常量API
  • JDK 13:Switch表达式(第二个预览版)、文本块(预览)
  • JDK 14:Switch表达式(正式版)、文本块(第二个预览版)、记录(预览)、NullPointerException增强
  • JDK 15:文本块(正式版)、记录(第二个预览版)、密封类(预览)、ZGC和Shenandoah成为生产特性
  • JDK 16:记录(正式版)、密封类(第二个预览版)、模式匹配 for instanceof(正式版)、Vector API(孵化器)
  • JDK 17:密封类(正式版)、模式匹配 for switch(预览)、增强的伪随机数生成器

这些特性使得Java语言更加现代化、简洁和高效,为开发者提供了更多的工具和选择。特别是记录、密封类和模式匹配等特性,大大简化了代码编写,提高了代码的可读性和可维护性。