Appearance
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语言更加现代化、简洁和高效,为开发者提供了更多的工具和选择。特别是记录、密封类和模式匹配等特性,大大简化了代码编写,提高了代码的可读性和可维护性。