97 lines
3.8 KiB
Markdown
97 lines
3.8 KiB
Markdown
---
|
||
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模式匹配。
|
||
- 记录类。
|
||
- 外部内存访问。
|