官网链接sealed class
从如下官网的简介与描述可以看出,这个新特性的目的是为了限制类与接口的 被继承与实现,比如说我有个 A类,那么我现在限定只有 B,C,D三个类可以继承 那么就需要用到这个新特性了
这个在JDK15,16中都作为了预览特性,在jdk17中正式发版 并且在jdk16后没有改动
The classes specified by permits
must be located near the superclass: either in the same module (if the superclass is in a named module) or in the same package (if the superclass is in the unnamed module).
When the permitted subclasses are small in size and number, it may be convenient to declare them in the same source file as the sealed class
如上两段话摘自官网 意思是说使用时 父子类的几种位置关系
package com.example.geometry;
public abstract sealed class Shape
permits Circle, Rectangle, Square { ... }
package com.example.geometry;
public abstract sealed class Shape
permits com.example.polar.Circle,
com.example.quad.Rectangle,
com.example.quad.simple.Square { ... }
abstract sealed class Root { ...
final class A extends Root { ... }
final class B extends Root { ... }
final class C extends Root { ... }
}
第一点 就是上面的1.2的前两点
第二点 每个permitted 子类 必须要直接继承 sealed 父类
第三点 permitted 子类 必须有三个修饰符之一 且不能同时存在
final(或者直接用record类):这个意思大家都懂 除此之外 因为 record数据类(顾名思义 他就是个用来传输数据 没有啥业务相关方法的类) 默认是final修饰 所以也能继承
package com.example.expression;
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 { ... }
sealed:用这个修饰符修饰的类 必须有子类 且要用 permitt 关键字后指明 如下报错可以看出
non-sealed 这个就跟上面这个相反 用这个修饰符修饰后 就不能指定 特定的类继承 该类了,并且未知的类就可以对他进行继承了
示例代码如下
package com.example.geometry;
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 { ... }
这里不多说了
使用 instanceof 前面那个实例所属类 如果是普通类 那么 编译通过 正常打印输出 如下demo
可以看到 当 C类没有实现了 I 接口时 编ins译报错 ,实现了的话就不会报错,因为这涉及到了一个强制转换的问题
permits子类中全为 final修饰 编译报错
反之,permits子类中不全为 final修饰 编译通过
下图中意思简要来说就是 我们不需要用if else来 结合instance of 判断,我们通过第二段代码所示的,使用switch case结合 密封类时 不需要写 default,并且如果少了某个子类的case时 会编译报错