记录 JDK-17 的新特征

懒驴 2021年09月20日 1,708次浏览

截止写稿日jdk已经更新到了17版本,最新版本的都具备哪些新的功能特性呢,让我们一起来了解看看吧!

从Java官网可以具体看到一下特征:
图1
JDK 17
JDK 17 是 Java SE 平台 17 版的开源参考实现,由Java Community Process 中的JSR 390指定 。

JDK 17达到总体供货14月在GPL下2021生产就绪的二进制文件可从Oracle ; 其他供应商的二进制文件将很快推出。

此版本的功能和时间表是通过JEP 流程提出并跟踪的,并由JEP 2.0 提案修订 。该版本是使用JDK Release Process (JEP 3) 生成的。


**特征**
  • 306: 恢复始终严格的浮点语义
  • 356: 增强型伪随机数发生器
  • 382: 新的 macOS 渲染管线
  • 391: macOS/AArch64 端口
  • 398: 弃用 Applet API 以进行删除
  • 403: 强封装JDK内部
  • 406: 开关模式匹配(预览)
  • 407: 删除 RMI 激活
  • 409: 密封类
  • 410: 删除实验性 AOT 和 JIT 编译器
  • 411: 弃用安全管理器以进行删除
  • 412: 外部函数和内存 API(孵化器)
  • 414: Vector API(第二孵化器)
  • 415: 上下文特定的反序列化过滤器

JDK 17 将成为大多数供应商的长期支持 (LTS) 版本.

1. Sealed修饰符

作用域:类、抽象类、接口。不可作用域内部类上

目标:声明一个类或为密封类,只有指定的类才可以继承改类。声明一个接口为密封接口,只有指定的接口可以继承该接口,只有指定的类可以实现该接口。

Sealed classes
- 子类与父类在同一包下声明方式
public abstract sealed class Shape
permits Circle, Rectangle, Square { ... }

- 子类与父类在统一模块下声明方式
public abstract sealed class Shape 
permits com.example.polar.Circle,
        com.example.quad.Rectangle,
        com.example.quad.simple.Square { ... }

- 子类与父类在同一 .java 文件下声明方式
abstract sealed class Root { ... 
final class A extends Root { ... }
final class B extends Root { ... }
final class C extends Root { ... }
}
- 声明注意:指定的类permits必须具有规范名称,否则会报告编译时错误。这意味着匿名类和本地类不能成为密封类的子类型。
- 声明效果:
	- 密封类及其允许的子类必须属于同一个模块,并且如果在未命名的模块中声明,则属于同一个包;
	- 每个允许的子类必须为final、sealed,或non-sealed;
	- 每个允许的子类必须使用修饰符来描述它如何传播由其超类发起的密封:
		- 可以声明允许的子类final以防止其在类层次结构中的部分被进一步扩展。(Record classes是隐式声明的final。)
		- 一个允许的子类可以被声明sealed为允许它的层次结构部分比其密封超类所设想的更进一步,但以一种受限的方式。
		- 可以声明一个允许的子类,non-sealed以便它的层次结构部分恢复为对未知子类的扩展开放。密封类不能阻止其允许的子类这样做。(修饰符non-sealed是 为 Java 提议的第一个带连字符的关键字。)

public abstract sealed class Shape
    permits Circle, Rectangle, Square, WeirdShape { ... }

public final class Circle extends Shape { ... }

public sealed class Rectangle extends Shape 
    permits TransparentRectangle, FilledRectangle { ... }
public final class TransparentRectangle extends Rectangle { ... }
public final class FilledRectangle extends Rectangle { ... }

public final class Square extends Shape { ... }

public non-sealed class WeirdShape extends Shape { ... } 

2. Sealed interfaces --- sealed修饰接口

    sealed interface Celestial 
    permits Planet, Star, Comet { ... }

final class Planet implements Celestial { ... }
final class Star   implements Celestial { ... }
final class Comet  implements Celestial { ... }

sealing与record classes使用
public sealed interface Expr
    permits ConstantExpr, PlusExpr, TimesExpr, NegExpr { ... }

public record ConstantExpr(int i)       implements Expr { ... }
public record PlusExpr(Expr a, Expr b)  implements Expr { ... }
public record TimesExpr(Expr a, Expr b) implements Expr { ... }
public record NegExpr(Expr e)           implements Expr { ... }
-范围特性: 该修饰符的出现是为了解决java类型范围不标准的问题,
-例如,如下代码是可以正常编译的,及时我们可以看出test方法没有意义。
interface I {}
class C {} // does not implement I

void test (C c) {
    if (c instanceof I) 
        System.out.println("It's an I");
}

JDK中的sealed使用案例:java.lang.constant.ConstantDesc

package java.lang.constant;
public sealed interface ConstantDesc    
permits String, Integer, Float, Long, Double,            ClassDesc, MethodTypeDesc, DynamicConstantDesc { ... }
// ClassDesc is designed for subclassing by JDK classes onlypublic sealed interface ClassDesc extends ConstantDesc    permits PrimitiveClassDescImpl, 
ReferenceClassDescImpl { ... }final class PrimitiveClassDescImpl 
implements ClassDesc { ... }final class ReferenceClassDescImpl
implements ClassDesc { ... } 
// MethodTypeDesc is designed for subclassing by JDK classes onlypublic sealed interface MethodTypeDesc extends ConstantDesc    permits MethodTypeDescImpl { ... }
final class MethodTypeDescImpl implements MethodTypeDesc { ... }
// DynamicConstantDesc is designed for subclassing by user 
codepublic non-sealed abstract class DynamicConstantDesc 
implements ConstantDesc { ... }

3. 反射相关

java.lang.Class添加了两个关于sealed的API

  • Class<?>[] getPermittedSubclasses()

  • boolean isSealed()

      如果该类是密封的,则该方法getPermittedSubclasses()
      返回一个包含java.lang.Class表示该类允许的子类的对象的数组 。
      如果类未密封,则返回一个空数组。
      isSealed如果给定的类或接口是密封的,则该方法返回 true。(比较isEnum。)
    

4. [持续更新中...]