blog/source/_posts/nf-java15.md
2021-05-25 09:56:20 +08:00

97 lines
3.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
title: Java 15的新特性
tags:
- JVM
- Java
- Java 15
- 新特性
- 记录类
- 密封类
- 隐藏类
categories:
- - JVM
- Java
keywords: 'Java,Java 15,新特性,记录类,密封类,隐藏类'
date: 2021-05-25 09:56:01
---
Java 15同样也是一个短期支持版其目的还是以功能稳定和功能演化为主。在Java 15中之前版本中的大部分功能还都依旧保持着预览版的状态真正能够进入稳定状态的功能并不多。
本系列的文章有:
- {% post_link nf-java8 %}
- {% post_link nf-java9 %}
- {% post_link nf-java10 %}
- {% post_link nf-java11 %}
- {% post_link nf-java12 %}
- {% post_link nf-java13 %}
- {% post_link nf-java14 %}
- {% post_link nf-java15 %}
- {% post_link nf-java16 %}
## 隐藏类
隐藏类的设计目标是允许运行时创建不可被发现的类。这种类不可以被其他类链接,也不能被反射所发现。隐藏类的生命周期通常比较短,而且主要用于框架设计。因为在框架中使用隐藏类可以避免框架用户直接调用框架内部的类。
隐藏类只能使用反射来创建,以下是创建隐藏类的示例。
```java
// 首先创建Lookup对象隐藏类只能通过Lookup::defineHiddenClass创建
MethodHandles.Lookup lookup = MethodHandles.lookup();
// 使用ASM创建类的字节码
ClassWriter cw = GenerateClass.getClassWriter(HiddenClassDemo.class);
byte[] bytes = cw.toByteArray();
// 创建隐藏类
Class<?> c = lookup.defineHiddenClass(bytes, true, NESTMATE).lookupClass();
// 使用隐藏类
Constructor<?> constructor = c.getConstructor(null);
Object object = constructor.newInstance(null);
Test test = (Test) object;
test.test(new String[]{""});
```
## 文本块
在经历了Java 13和Java 14两个版本的预览文本块功能在Java 15中获得了转正。现在文本块功能已经足够稳定并且可以在生产环境下使用了。
文本块的功能相较之前两个预览版没有发生什么变化所以具体使用可以参考之前Java版本特性叙述中的示例。
## 预览版功能
### 密封类
密封类提供了对于继承的更细粒度的控制。密封类可以允许指定的类成为密封类的子类从而严格控制子类的存在。为了实现密封类Java 15引入了三个新的关键字:`sealed`、`non-sealed`和`permits`。
密封类的创建和使用必须遵循以下几条规则。
1. 密封类和被允许的子类必须位于同一个模块中,如果没有定义模块,则必须位于同一个包中。
1. 被允许的子类必须直接继承密封类。
1. 被允许的子类必须显式声明它如何继续控制继承性,可用的关键字有`final`、`sealed`和`non-sealed`。
1. 被允许的子类可以选择使用`final`修饰,这样这个子类就不能再被继承了。
1. 被允许的子类可以选择使用`sealed`修饰,这样这个子类就将依旧需要使用`permits`来控制其子类。
1. 被允许的子类可以选择使用`non-sealed`修饰,这样这个子类将完全对任何继承开放。
以下是密封类规则的示例。
```java
// 定义一个密封类仅允许Circle等三个类继承它
public abstract sealed class Shape
permits Circle, Rectangle, Square { }
// Circle类禁止其他的类再继承它
public final class Circle extends Shape { }
// Rectangle类继续保持了密封特性并仅允许一部分子类继承
public sealed class Rectangle extends Shape
permits FilledRectangle, TransparentRectangle { }
public final class FilledRectangle extends Rectangle { }
// Square类对于继承是完全开放的
public non-sealed class Square extends Shape { }
```
### 其他预览版功能
以下这些预览版功能还依旧在之前版本基础之上继续发展,尚未进入到完全稳定的状态。
- instanceOf模式匹配。
- 记录类。
- 外部内存访问。