第四天:Java 13到Java 16新特性

第四天:Java 13到Java 16新特性

今天我们将学习Java 13到Java 16的新特性。这些版本引入了许多实验性功能,其中一些在后续版本中得到了标准化。

Java 13新特性

Java 13于2019年9月发布,继续改进了一些预览功能并引入了新的特性。

1. 文本块(预览)

Java 13引入了文本块作为预览功能,使多行字符串的表示更加简洁和直观。

// Java 12及之前
String json = "{\n" +
              "    \"name\": \"John Doe\",\n" +
              "    \"age\": 30,\n" +
              "    \"address\": {\n" +
              "        \"street\": \"123 Main St\",\n" +
              "        \"city\": \"Anytown\"\n" +
              "    }\n" +
              "}";

// Java 13(预览)
String json = """
              {
                  "name": "John Doe",
                  "age": 30,
                  "address": {
                      "street": "123 Main St",
                      "city": "Anytown"
                  }
              }
              """;
+------------------+     +------------------+
| 传统字符串       |     | 文本块           |
+------------------+     +------------------+
| "line1\n" +      |     | """              |
| "line2\n" +      |     |   line1          |
| "line3"          |     |   line2          |
|                  |     |   line3          |
|                  |     | """              |
+------------------+     +------------------+

2. Switch表达式更新(预览)

Java 13更新了Switch表达式,引入了yield语句来返回值。

// Java 12
int numLetters = switch (day) {
    case MONDAY, FRIDAY, SUNDAY -> 6;
    case TUESDAY                -> 7;
    case THURSDAY, SATURDAY     -> 8;
    case WEDNESDAY              -> 9;
    default                     -> 0;
};

// Java 13
int numLetters = switch (day) {
    case MONDAY, FRIDAY, SUNDAY -> 6;
    case TUESDAY                -> 7;
    case THURSDAY, SATURDAY     -> 8;
    case WEDNESDAY              -> 9;
    default                     -> {
        System.out.println("Unknown day: " + day);
        yield 0;
    }
};
+------------------+     +------------------+
| Java 12 Switch   |     | Java 13 Switch   |
+------------------+     +------------------+
| case MONDAY ->   |     | case MONDAY ->   |
|   6;             |     |   6;             |
|                  |     |                  |
| default -> 0;    |     | default -> {     |
|                  |     |   System.out.    |
|                  |     |   println(...);  |
|                  |     |   yield 0;       |
|                  |     | }                |
+------------------+     +------------------+

3. 重新实现Socket API

Java 13重新实现了Socket API,使用NIO实现,提高了可维护性和性能。

// 旧的Socket API
Socket socket = new Socket("example.com", 80);
OutputStream out = socket.getOutputStream();
InputStream in = socket.getInputStream();

// 新的Socket API(内部实现变化,API保持不变)
Socket socket = new Socket("example.com", 80);
OutputStream out = socket.getOutputStream();
InputStream in = socket.getInputStream();
+------------------+     +------------------+
| 旧Socket实现     |     | 新Socket实现     |
+------------------+     +------------------+
| 遗留代码         |     | NIO实现          |
| 难以维护         |     | 更易维护         |
| 性能较低         |     | 性能更好         |
| 不支持异步操作   |     | 支持异步操作     |
+------------------+     +------------------+

4. ZGC:取消提交未使用内存

Java 13改进了ZGC垃圾收集器,使其能够将未使用的内存返回给操作系统。

# 启用ZGC并允许取消提交未使用内存
java -XX:+UnlockExperimentalVMOptions -XX:+UseZGC -XX:+ZUncommit -jar app.jar
+------------------+     +------------------+
| ZGC改进前        |     | ZGC改进后        |
+------------------+     +------------------+
| 分配内存         |     | 分配内存         |
| 回收垃圾         |     | 回收垃圾         |
| 保留所有内存     |     | 取消提交未使用   |
|                  |     | 内存             |
+------------------+     +------------------+

5. 其他Java 13特性

  • 动态CDS归档:增强了类数据共享(CDS)功能,允许在应用程序执行结束时动态归档类。
  • FileSystems.newFileSystem()方法:添加了新的工厂方法来创建FileSystem对象。

Java 14新特性

Java 14于2020年3月发布,引入了多个新特性和预览功能。

1. Switch表达式(标准化)

Java 14将Switch表达式标准化,不再是预览功能。

// Java 14标准化的Switch表达式
int numLetters = switch (day) {
    case MONDAY, FRIDAY, SUNDAY -> 6;
    case TUESDAY                -> 7;
    case THURSDAY, SATURDAY     -> 8;
    case WEDNESDAY              -> 9;
    default                     -> {
        System.out.println("Unknown day: " + day);
        yield 0;
    }
};
+------------------+     +------------------+
| 传统Switch语句   |     | Switch表达式     |
+------------------+     +------------------+
| 语句形式         |     | 表达式形式       |
| 需要break语句    |     | 不需要break语句  |
| 容易出错         |     | 更安全           |
| 不能直接赋值     |     | 可以直接赋值     |
+------------------+     +------------------+

2. 记录类(预览)

Java 14引入了记录类(Record)作为预览功能,用于创建不可变的数据类。

// Java 14(预览)
record Point(int x, int y) {
    // 自动生成:
    // - 构造函数
    // - 访问器方法 x() 和 y()
    // - equals() 和 hashCode()
    // - toString()
    
    // 可以添加静态字段和方法
    public static Point origin() {
        return new Point(0, 0);
    }
    
    // 可以添加实例方法
    public double distanceFromOrigin() {
        return Math.sqrt(x * x + y * y);
    }
    
    // 可以自定义构造函数
    public Point {
        if (x < 0 || y < 0) {
            throw new IllegalArgumentException("Coordinates cannot be negative");
        }
    }
}

// 使用记录类
Point p = new Point(3, 4);
System.out.println(p); // Point[x=3, y=4]
System.out.println(p.x()); // 3
System.out.println(p.y()); // 4
System.out.println(p.distanceFromOrigin()); // 5.0
+------------------+     +------------------+
| 传统数据类       |     | 记录类           |
+------------------+     +------------------+
| class Point {    |     | record Point(    |
|   private final  |     |   int x,         |
|   int x, y;      |     |   int y          |
|   // 构造函数    |     | ) {              |
|   // getter      |     |   // 自动生成    |
|   // equals()    |     |   // 构造函数    |
|   // hashCode()  |     |   // 访问器      |
|   // toString()  |     |   // equals()    |
| }                |     |   // hashCode()  |
|                  |     |   // toString()  |
+------------------+     +------------------+

3. 模式匹配for instanceof(预览)

Java 14引入了instanceof的模式匹配作为预览功能,简化了类型检查和转换。

// Java 14之前
if (obj instanceof String) {
    String s = (String) obj;
    System.out.println(s.length());
}

// Java 14(预览)
if (obj instanceof String s) {
    System.out.println(s.length());
}
+------------------+     +------------------+
| 传统instanceof   |     | 模式匹配instanceof|
+------------------+     +------------------+
| if (obj instanceof|    | if (obj instanceof|
|   String) {       |    |   String s) {     |
|   String s =      |    |                   |
|     (String) obj; |    |                   |
|   ...             |    |   ...             |
| }                 |    | }                 |
+------------------+     +------------------+

4. 有用的NullPointerException

Java 14改进了NullPointerException的错误消息,提供了更详细的信息,帮助开发者更快地定位问题。

// Java 14之前
person.getAddress().getStreet(); // 如果getAddress()返回null
// NullPointerException

// Java 14
person.getAddress().getStreet();
// NullPointerException: Cannot invoke "Address.getStreet()" because the return value of "Person.getAddress()" is null
+------------------+     +------------------+
| 传统NPE消息      |     | 增强NPE消息      |
+------------------+     +------------------+
| NullPointer      |     | NullPointer      |
| Exception        |     | Exception:       |
|                  |     | Cannot invoke    |
|                  |     | "Address.get     |
|                  |     | Street()" because|
|                  |     | the return value |
|                  |     | of "Person.get   |
|                  |     | Address()" is null|
+------------------+     +------------------+

5. 打包工具(孵化器)

Java 14引入了jpackage工具作为孵化器功能,用于打包自包含的Java应用程序。

# 创建可执行文件
jpackage --name myapp --input lib --main-jar myapp.jar

# 创建安装程序
jpackage --name myapp --input lib --main-jar myapp.jar --type dmg
+------------------+     +------------------+
| jpackage流程     |     |                  |
+------------------+     |                  |
| Java应用程序     |     |                  |
|       |          |     |                  |
|       v          |     |                  |
| jpackage工具     |     |                  |
|       |          |     |                  |
|       v          |     |                  |
| 平台特定安装包   |     |                  |
| (exe, dmg, deb,  |     |                  |
| rpm等)           |     |                  |
+------------------+     +------------------+

6. 非易失性映射字节缓冲区

Java 14增强了MappedByteBuffer,添加了非易失性内存支持。

// 创建非易失性映射字节缓冲区
FileChannel fileChannel = FileChannel.open(path, StandardOpenOption.READ, StandardOpenOption.WRITE);
MappedByteBuffer buffer = fileChannel.map(FileChannel.MapMode.READ_WRITE, 0, size);

7. 其他Java 14特性

  • 删除CMS垃圾收集器:移除了CMS(Concurrent Mark Sweep)垃圾收集器。
  • 弃用ParallelScavenge + SerialOld GC组合:标记为弃用。
  • ZGC在macOS和Windows上可用:ZGC现在可以在macOS和Windows上使用。
  • 外部存储器访问API(孵化器):引入了用于访问Java堆外内存的API。

Java 15新特性

Java 15于2020年9月发布,继续改进了一些预览功能并引入了新的特性。

1. 文本块(标准化)

Java 15将文本块标准化,不再是预览功能。

// Java 15标准化的文本块
String html = """
              <html>
                  <body>
                      <p>Hello, World!</p>
                  </body>
              </html>
              """;

2. 密封类(预览)

Java 15引入了密封类(Sealed Classes)作为预览功能,允许类的作者控制哪些类可以继承该类。

// Java 15(预览)
public sealed class Shape permits Circle, Rectangle, Square {
    // ...
}

public final class Circle extends Shape {
    // ...
}

public non-sealed class Rectangle extends Shape {
    // ...
}

public final class Square extends Rectangle {
    // ...
}

// 尝试创建未经许可的子类
public class Triangle extends Shape { // 编译错误:Triangle不在permits列表中
    // ...
}
+------------------+     +------------------+
| 密封类层次结构   |     |                  |
+------------------+     |                  |
|     Shape        |     |                  |
|    (sealed)      |     |                  |
|    /  |  \       |     |                  |
|   /   |   \      |     |                  |
| Circle Rectangle |     |                  |
|(final)(non-sealed)|    |                  |
|          |       |     |                  |
|          |       |     |                  |
|       Square     |     |                  |
|      (final)     |     |                  |
+------------------+     +------------------+

3. 隐藏类

Java 15引入了隐藏类,这些类不能被普通字节码直接使用,主要用于框架生成运行时类。

// 创建隐藏类
byte[] classBytes = ...; // 类的字节码
Class<?> hiddenClass = Lookup.defineHiddenClass(classBytes, false, ClassOption.NESTMATE).lookupClass();

// 使用隐藏类
Object instance = hiddenClass.newInstance();
Method method = hiddenClass.getMethod("someMethod");
method.invoke(instance);
+------------------+     +------------------+
| 普通类           |     | 隐藏类           |
+------------------+     +------------------+
| 可以通过名称引用 |     | 不能通过名称引用 |
| 可以被反射访问   |     | 有限的反射访问   |
| 长期存在         |     | 可以被卸载       |
| 可以被任何代码   |     | 只能被创建它的   |
| 访问             |     | 代码访问         |
+------------------+     +------------------+

4. 记录类和模式匹配的第二次预览

Java 15对记录类和instanceof的模式匹配进行了第二次预览,进一步改进了这些功能。

5. 爱德华兹曲线算法

Java 15引入了爱德华兹曲线(Edwards-Curve)数字签名算法实现。

// 生成密钥对
KeyPairGenerator kpg = KeyPairGenerator.getInstance("Ed25519");
KeyPair kp = kpg.generateKeyPair();
PrivateKey privateKey = kp.getPrivate();
PublicKey publicKey = kp.getPublic();

// 签名
Signature sig = Signature.getInstance("Ed25519");
sig.initSign(privateKey);
sig.update(data);
byte[] signature = sig.sign();

// 验证
sig.initVerify(publicKey);
sig.update(data);
boolean valid = sig.verify(signature);
+------------------+     +------------------+
| 传统签名算法     |     | Ed25519算法      |
+------------------+     +------------------+
| RSA, DSA, ECDSA  |     | Edwards-Curve    |
| 较慢             |     | 更快             |
| 密钥较大         |     | 密钥较小         |
| 安全性较低       |     | 安全性较高       |
+------------------+     +------------------+

6. 废弃偏向锁

Java 15废弃了偏向锁(Biased Locking),计划在未来版本中移除。

# 禁用偏向锁
java -XX:-UseBiasedLocking -jar app.jar

7. ZGC生产就绪

Java 15将ZGC从实验性功能升级为产品功能,可以在生产环境中使用。

# 启用ZGC
java -XX:+UseZGC -jar app.jar
+------------------+     +------------------+
| ZGC特点          |     | 优势             |
+------------------+     +------------------+
| 低延迟垃圾收集器 |     | 暂停时间<1ms     |
| 并发处理         |     | 不影响应用程序   |
|                  |     | 线程             |
| 可扩展           |     | 从8MB到16TB堆    |
| 彩色指针         |     | 高效内存管理     |
+------------------+     +------------------+

8. Shenandoah GC生产就绪

Java 15将Shenandoah GC从实验性功能升级为产品功能,可以在生产环境中使用。

# 启用Shenandoah GC
java -XX:+UseShenandoahGC -jar app.jar

9. 其他Java 15特性

  • 外部存储器访问API(第二次孵化):继续改进外部存储器访问API。
  • DatagramSocket API重新实现:重新实现了DatagramSocket API。
  • 禁用和废弃偏向锁:默认禁用偏向锁,并将其标记为废弃。

Java 16新特性

Java 16于2021年3月发布,继续改进了一些预览功能并引入了新的特性。

1. 记录类(标准化)

Java 16将记录类标准化,不再是预览功能。

// Java 16标准化的记录类
record Point(int x, int y) {
    // 自动生成:
    // - 构造函数
    // - 访问器方法 x() 和 y()
    // - equals() 和 hashCode()
    // - toString()
    
    // 可以添加静态字段和方法
    public static Point origin() {
        return new Point(0, 0);
    }
    
    // 可以添加实例方法
    public double distanceFromOrigin() {
        return Math.sqrt(x * x + y * y);
    }
    
    // 可以自定义构造函数
    public Point {
        if (x < 0 || y < 0) {
            throw new IllegalArgumentException("Coordinates cannot be negative");
        }
    }
}

2. 模式匹配for instanceof(标准化)

Java 16将instanceof的模式匹配标准化,不再是预览功能。

// Java 16标准化的instanceof模式匹配
if (obj instanceof String s) {
    System.out.println(s.length());
}

3. 密封类(第二次预览)

Java 16对密封类进行了第二次预览,进一步改进了这个功能。

// Java 16(第二次预览)
public sealed class Shape permits Circle, Rectangle, Square {
    // ...
}

4. 向量API(孵化器)

Java 16引入了向量API作为孵化器功能,用于表达向量计算。

// Java 16(孵化器)
// 使用向量API进行SIMD操作
IntVector a = IntVector.fromArray(IntVector.SPECIES_128, new int[]{1, 2, 3, 4}, 0);
IntVector b = IntVector.fromArray(IntVector.SPECIES_128, new int[]{5, 6, 7, 8}, 0);
IntVector c = a.add(b);
// c包含[6, 8, 10, 12]
+------------------+     +------------------+
| 标量计算         |     | 向量计算         |
+------------------+     +------------------+
| for (int i = 0;  |     | IntVector a =    |
|   i < arr.length;|     |   IntVector.from |
|   i++) {         |     |   Array(...);    |
|   result[i] =    |     | IntVector b =    |
|     arr1[i] +    |     |   IntVector.from |
|     arr2[i];     |     |   Array(...);    |
| }                |     | IntVector c =    |
|                  |     |   a.add(b);      |
+------------------+     +------------------+

5. 外部存储器访问API(孵化器)

Java 16继续改进外部存储器访问API,这是第三次孵化。

// Java 16(孵化器)
// 分配堆外内存
MemorySegment segment = MemorySegment.allocateNative(100);
// 写入数据
segment.set(ValueLayout.JAVA_INT, 0, 42);
// 读取数据
int value = segment.get(ValueLayout.JAVA_INT, 0);
// 释放内存
segment.close();
+------------------+     +------------------+
| 传统堆外内存     |     | 外部存储器访问API|
+------------------+     +------------------+
| ByteBuffer.      |     | MemorySegment.   |
| allocateDirect() |     | allocateNative() |
| 有限的类型支持   |     | 丰富的类型支持   |
| 手动管理内存     |     | 自动释放资源     |
| 容易出错         |     | 更安全           |
+------------------+     +------------------+

6. 打包工具(孵化器)

Java 16继续改进jpackage工具,这是第二次孵化。

# 创建可执行文件
jpackage --name myapp --input lib --main-jar myapp.jar

# 创建安装程序
jpackage --name myapp --input lib --main-jar myapp.jar --type dmg

7. Unix域套接字

Java 16添加了对Unix域套接字(Unix Domain Socket)的支持。

// 创建Unix域套接字服务器
UnixDomainSocketAddress address = UnixDomainSocketAddress.of("/tmp/server.sock");
ServerSocketChannel serverChannel = ServerSocketChannel.open(StandardProtocolFamily.UNIX);
serverChannel.bind(address);
SocketChannel channel = serverChannel.accept();

// 创建Unix域套接字客户端
SocketChannel clientChannel = SocketChannel.open(StandardProtocolFamily.UNIX);
clientChannel.connect(address);
+------------------+     +------------------+
| TCP/IP套接字     |     | Unix域套接字     |
+------------------+     +------------------+
| 网络通信         |     | 同一主机通信     |
| 较高开销         |     | 较低开销         |
| 需要网络栈       |     | 不需要网络栈     |
| 安全性较低       |     | 安全性较高       |
+------------------+     +------------------+

8. 弹性元空间

Java 16引入了弹性元空间,更高效地将未使用的HotSpot类元数据内存(元空间)返回给操作系统。

# 配置元空间
java -XX:MetaspaceSize=64m -XX:MaxMetaspaceSize=256m -jar app.jar
+------------------+     +------------------+
| 传统元空间       |     | 弹性元空间       |
+------------------+     +------------------+
| 分配大块内存     |     | 分配小块内存     |
| 很少释放内存     |     | 积极释放内存     |
| 内存使用效率低   |     | 内存使用效率高   |
+------------------+     +------------------+

9. 启用C++14语言特性

Java 16在JDK源代码中启用了C++14语言特性,这是JDK内部实现的改进。

10. 迁移到GitHub

Java 16将JDK源代码存储库从Mercurial迁移到了GitHub。

11. 其他Java 16特性

  • Alpine Linux端口:为Alpine Linux添加了JDK端口。
  • Windows/AArch64端口:为Windows/AArch64添加了JDK端口。
  • ZGC并发线程处理:改进了ZGC的并发线程处理。
  • 禁用偏向锁:默认禁用偏向锁。

总结

Java 13到Java 16引入了许多重要的新特性和改进,包括:

Java 13主要特性:

  1. 文本块(预览)
  2. Switch表达式更新(预览)
  3. 重新实现Socket API
  4. ZGC:取消提交未使用内存
  5. 动态CDS归档

Java 14主要特性:

  1. Switch表达式(标准化)
  2. 记录类(预览)
  3. 模式匹配for instanceof(预览)
  4. 有用的NullPointerException
  5. 打包工具(孵化器)
  6. 非易失性映射字节缓冲区

Java 15主要特性:

  1. 文本块(标准化)
  2. 密封类(预览)
  3. 隐藏类
  4. 记录类和模式匹配的第二次预览
  5. 爱德华兹曲线算法
  6. ZGC生产就绪
  7. Shenandoah GC生产就绪

Java 16主要特性:

  1. 记录类(标准化)
  2. 模式匹配for instanceof(标准化)
  3. 密封类(第二次预览)
  4. 向量API(孵化器)
  5. 外部存储器访问API(孵化器)
  6. 打包工具(孵化器)
  7. Unix域套接字
  8. 弹性元空间

这些新特性使Java更加现代化、简洁和高效,为开发者提供了更多的工具和选择。

+------------------+     +------------------+     +------------------+     +------------------+
|   Java 13特性    |     |   Java 14特性    |     |   Java 15特性    |     |   Java 16特性    |
+------------------+     +------------------+     +------------------+     +------------------+
| 文本块(预览)     |     | Switch表达式     |     | 文本块           |     | 记录类           |
| Switch表达式更新 |     | 记录类(预览)     |     | 密封类(预览)     |     | 模式匹配instanceof|
| 重新实现Socket   |     | 模式匹配instanceof|    | 隐藏类           |     | 密封类(第二次预览)|
| ZGC改进          |     | 有用的NPE        |     | 爱德华兹曲线算法 |     | 向量API(孵化器)  |
| 动态CDS归档      |     | 打包工具(孵化器) |     | ZGC生产就绪      |     | 外部存储器访问API|
|                  |     | 非易失性映射     |     | Shenandoah生产   |     | 打包工具(孵化器) |
|                  |     | 字节缓冲区       |     | 就绪             |     | Unix域套接字     |
|                  |     |                  |     |                  |     | 弹性元空间       |
+------------------+     +------------------+     +------------------+     +------------------+

练习

  1. 使用文本块创建HTML、JSON或SQL字符串。
  2. 使用Switch表达式简化代码。
  3. 创建并使用记录类表示不可变数据。
  4. 使用instanceof的模式匹配简化类型检查和转换。
  5. 尝试使用密封类控制继承层次结构。

参考资料

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值