sealed 类型限定了谁能继承它。运行时怎么看到这个限定?编译期与运行期各自检查什么?新增子类后旧代码会怎样?这篇用反射、javap 和有意制造的版本不一致逐项验证。
Shape.isSealed() = true,isInterface = true,修饰符 = public abstract interface
Shape.getPermittedSubclasses() = [Circle, Square, Poly]
Circle isSealed=false final=true record=true 修饰符=public final
Square isSealed=false final=true record=false 修饰符=public final
Poly isSealed=false final=false record=false 修饰符=public
非 sealed 类 Poly.getPermittedSubclasses() = null(null 表示不是 sealed);Tri 继承 non-sealed 的 Poly,Tri.isSealed() = false
Shape.class.getPermittedSubclasses() 的顺序与源码 permits 的顺序:[Circle, Square, Poly](源码是 Circle, Square, Poly) javap -v shapes.Shape 里的属性:
PermittedSubclasses
#8 = Class #9 // shapes/Circle
#9 = Utf8 shapes/Circle
#10 = Class #11 // shapes/Square
#11 = Utf8 shapes/Square
Circle 的 class 文件里有 PermittedSubclasses 吗: False ;Poly(non-sealed)里有吗: Falsejavac:不在 permits 里的 Extra implements Shape → ["<jtmp>/j84b/shapes/Extra.java:1: error: class is not allowed to extend sealed class: Shape (as it is not listed in its 'permits' clause)"] javac:允许的子类 Square 没有写 final / sealed / non-sealed → ['<jtmp>/j84c/shapes/Square.java:1: error: sealed, non-sealed or final modifiers expected'] 运行时:Extra.class 声明继承 Shape,但新的 Shape.class 的 permits 里没有它 → IncompatibleClassChangeError: class shapes.Extra cannot implement sealed interface shapes.Shape
circle square poly 旧的 App.class 遇到新子类 Hexagon → java.lang.MatchException: null App.name 的字节码里有 MatchException: True ;invokedynamic typeSwitch: True