首页
学习
活动
专区
圈层
工具
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

JDK 17 正式推出的密封类(Sealed Classes)都有什么作用?

在JDK 17中,Java正式推出一个非常有趣的新特性——密封类(Sealed Classes),这是个什么新鲜玩意,让我们一起研究下。

一、什么是密封类?

密封类其实是一种限制继承的类。我们可以把它想象成一个封闭的社区,只有某些特定的人(类)可以进入(继承)。而其他不被允许的人(类)不能进入。

在传统的Java中,类是没有继承限制的,任何类都可以继承其它类。比如:

class Animal {}

class Dog extends Animal {}  // Dog可以继承Animal

class Cat extends Animal {}  // Cat也可以继承Animal

但是,在一些情况下,我们希望限制类的继承,确保只有某些类能够继承。这时候,密封类就派上了用场。

JDK发布密封类的重要节点:

二、密封类的设计初衷

密封类的设计初衷主要是为了更好地控制类的继承关系,避免一些可能的错误或者不合适的继承。

通过限制类的继承,我们可以:

确保继承的结构是安全和可控的。

减少不必要的继承,让类的设计更加清晰。

在传统的Java中,任何类都可以继承其他类,这虽然灵活,但也可能带来一些问题。

例如,如果某个类被不合适的子类继承,可能会破坏原本的设计或者引入错误。密封类通过明确列出允许继承的子类,避免了这种情况。

三、密封类的优点

明确的继承关系

密封类通过permits关键字清晰地列出允许继承的类,避免了继承链变得混乱不清。这样,开发者可以清楚地知道,哪些类是可以扩展的,哪些类是不允许继承的。

增加类型安全

使用密封类,可以确保只有特定的子类才能继承它,这减少了因为继承不当导致的错误。例如,你不希望某个类被滥用或被错误地继承,那么密封类就能很好地保护你的类。

简化代码和提高可维护性

通过限制继承关系,密封类能减少复杂的继承层级,使代码更加简洁和易于理解。尤其在大规模项目中,密封类有助于保持代码的可维护性。

性能优化

JVM可以根据密封类的继承结构进行优化,特别是在判断类类型和方法调用时,性能可以得到提升。因为JVM知道密封类的继承是有限的,它可以做出更高效的优化。

四、如何使用密封类

1. 定义密封类

要定义一个密封类,我们使用sealed关键字,并permits关键字指定哪些类可以继承它。

例如:

public sealed class Animal permits Dog, Cat {

  // Animal类的实现

}

这里,Animal是密封类,Dog和Cat是被允许继承它的类。这样,只有Dog和Cat能继承Animal,其他任何类都不能。

2. 继承密封类

继承密封类时,子类必须声明它们是继承了密封类的,并且必须是final(表示不能进一步继承)或sealed(表示它也可以被某些类继承)。

public final class Dog extends Animal {

  // Dog类继承Animal类

}

public final class Cat extends Animal {

  // Cat类继承Animal类

}

在这个例子中,Dog和Cat都是final类,表示它们不能再被继承。

3. 禁止不合法继承

如果尝试让一个类继承密封类,但该类没有在permits中列出,编译器会报错。例如:

public class Bird extends Animal {

  // 编译错误:Bird不能继承Animal

}

这里,Bird没有被列为允许继承Animal的类,因此会导致编译错误。

五、密封类的实际应用

密封类特别适合于那些我们希望限制继承结构的场景。

例如,我们在开发一个图形库,可能只希望某些特定的形状(如圆形、矩形、三角形等)继承一个通用的Shape类,而不希望其他不相关的类继承它。

public sealed class Shape permits Circle, Rectangle, Triangle {

  public abstract double area();

}

publicfinalclass Circle extends Shape {

  privatedouble radius;

  public Circle(double radius) {

      this.radius = radius;

  }

  @Override

  public double area() {

      return Math.PI * radius * radius;

  }

}

publicfinalclass Rectangle extends Shape {

  privatedouble length, width;

  public Rectangle(double length, double width) {

      this.length = length;

      this.width = width;

  }

  @Override

  public double area() {

      return length * width;

  }

}

publicfinalclass Triangle extends Shape {

  privatedouble base, height;

  public Triangle(double base, double height) {

      this.base = base;

      this.height = height;

  }

  @Override

  public double area() {

      return0.5 * base * height;

  }

}

在这个例子中,Shape是一个密封类,它只允许Circle、Rectangle和Triangle继承。这样做可以确保,只有这些特定的类能继承Shape类并实现area()方法。

最后总结

JDK 17 的密封类(Sealed Classes)为Java带来了更多的灵活性和控制能力。

它通过限制类的继承关系,增强了类型安全性,减少了潜在的错误,并且提高了代码的可维护性。尤其在一些特定场景中,密封类能够帮助开发者实现更精确的设计。

密封类,揭开它神秘的面纱,也就不神秘了。

  • 发表于:
  • 原文链接https://page.om.qq.com/page/OPrXeQxtvjolLl26DKW0mfpg0
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券