From c1b9cca6034afa30036219858ea1dde9b5158af7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BE=90=E6=B6=9B?= Date: Tue, 25 May 2021 09:56:20 +0800 Subject: [PATCH] =?UTF-8?q?post:=E5=AE=8C=E6=88=90Java=2015=E7=9A=84?= =?UTF-8?q?=E6=96=B0=E7=89=B9=E6=80=A7=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- source/_posts/nf-java15.md | 96 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 96 insertions(+) create mode 100644 source/_posts/nf-java15.md diff --git a/source/_posts/nf-java15.md b/source/_posts/nf-java15.md new file mode 100644 index 0000000..a57e0e9 --- /dev/null +++ b/source/_posts/nf-java15.md @@ -0,0 +1,96 @@ +--- +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模式匹配。 +- 记录类。 +- 外部内存访问。