本文主要是介绍jdk15至17——sealed密封关键字,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
sealed关键字是从jdk15开始预览,直到jdk17成为正式版,可以对继承父类和实现接口进行更加细粒度的限制,之前的限制也只有final用于禁止继承,默认包权限限制在同一个包内,sealed密封类/接口可以明确指定哪些类可以进行继承和实现;
跟sealed相关的关键字除了之前的final,还有新增的non-sealed和permits:
- permits:用于明确指定允许继承的子类和实现类,且不能使用匿名类动态类,书写位置在extends/implements后面(大概是放最后面);
- sealed:指定类/接口为密封类/接口,后面必须使用permits指定子类/实现类;
- final:指定类为最终类,不能被继承;
- non-sealed:解除密封性,指定为普通类关系;
sealed可以修饰类也可以修饰接口,密封类的子类必须使用sealed、final、non-sealed其中之一修饰,sealed修饰的子类继续密封,后面继续使用permits指定,final修饰的子类为最终类,不能被继承,non-sealed修饰的子类密封性解除,后续可以当普通类使用;
permits指定的允许类为直接指定,不具有传递性;
代码展示:
package test;public class MainTest {//密封类A只能被A1,A2,A3继承public sealed class A permits A1, A2, A3 {}//A1为final类,不能继续被继承public final class A1 extends A {}//A2使用non-sealed修饰,解除密封限制可被任何类继承public non-sealed class A2 extends A {}//A3仍为密封类,需要继续用permits指定可继承类public sealed class A3 extends A permits B {}public final class B extends A3 {}// public final class A4 extends A {} //报错,A4未被A指定未可继承类public class C extends A2 {} //任何类都可继承A2public static void main(String[] args) {}}
另外,sealed类和子类/实现类,可以在同一个包下,也可以在不同的包下,但是必须在同一个模块下,如果使用未命名的模块,则必须在同一个包里;
需要在不同包里使用时需要建一个命名的模块:
另外,由于record类型最后编译成final类并且不支持继承和被继承,所以可以跟sealed接口一起使用,使代码更简介:
package test;public class MainTest {public sealed interface A permits B, C {public void fun();}public record B(String s) implements A {@Overridepublic void fun() {System.out.println("B fun:" + s);}}public record C(int i) implements A {@Overridepublic void fun() {System.out.println("C fun:" + i);}}public static void main(String[] args) {A b = new B("abc");A c = new C(321);b.fun();c.fun();}}
这篇关于jdk15至17——sealed密封关键字的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!