The new feature Sealed Classes introduced by Java 17 has gone through 2 Preview versions (JEP 360 in JDK 15 and JEP 397 in JDK 16), and was finally finalized in JEP 409 in JDK 17. There are two mainstream translations of Sealed Classes: sealed and closed. Personally, I like the former more, so it is called sealed class in this article. In fact, many other languages of Sealed Classes are nothing new. There are similar names in high-level languages such as C# and Scala, but their meanings and functions are different. Let's take a look at Sealed Classes in Java 17.
The role of sealing
In object-oriented languages, we can reuse, extend and enhance the capabilities of classes through inheritance. But sometimes, some capabilities we don't want to be inherited to do some unpredictable extensions. So, we need some means of controlling the inheritance relationship with some restrictions. The role of a sealed class is to restrict class inheritance .
existing restrictions
For the control of inheritance capabilities, Java has already had some for a long time, mainly in these two ways:
-
final
modify the class so that the class cannot be inherited -
package-private
class (non-public class), which can only be inherited by classes in the same package
But obviously, the granularity of these two restriction methods is very coarse, and if there is a more refined restriction requirement, it is difficult to achieve.
New Feature: Sealed Classes
To further enhance confinement capabilities, several important keywords have been added to sealed classes in Java 17:
-
sealed
: Modified class/interface, used to describe this class/interface as a sealed class/interface -
non-sealed
: Modified class/interface, used to describe this class/interface as a non-sealed class/interface -
permits
: used afterextends
andimplements
to specify a class that can be inherited or implemented
Let's use an example to understand the usage of these keywords. For more new Java features, welcome to pay attention to the Java frontier column , see the new Java features in the document format, and have a better reading and learning experience. Keep updating and saving!
Suppose we want to design a game. The hero types that the game gives users to choose are divided into three categories:
- tank
- output
- Auxiliary
There are various specific heroes under each category. So, from our traditional design-oriented thinking, we will create it like this:
// 英雄基类
public class Hero {
}
// 坦克英雄的抽象
public class TankHero extends Hero {
}
// 输出英雄的抽象
public class AttackHero extends Hero {
}
// 辅助英雄的抽象
public class SupportHero extends Hero {
}
// 坦克英雄:阿利斯塔
public class Alistar extends TankHero {
}
// 输出英雄:伊泽瑞尔
public class Ezreal extends AttackHero {
}
// 辅助英雄:索拉卡
public class Soraka extends SupportHero {
}
The overall structure has three layers, as shown in the following figure:
- The first layer: Hero is the base class of all heroes, defining the basic attributes of heroes
- The second layer: three different abstractions according to the classification of heroes, define the common attributes of heroes of the same type
- Layer 3: Definition of Specific Heroes
At this time, in order to avoid developers messing up such a three-tier structure when creating new heroes. It can be restricted by introducing the characteristics of sealed classes.
Suppose we want the first and second layers to be stable, and the abstraction of the second layer of hero types is not allowed to increase. At this time, we can write as follows:
public sealed class Hero permits TankHero, AttackHero, SupportHero {
}
sealed
关键词permitspermits
关键来定义Hero是一个需要密封的类,并且它的子类只TankHero
, AttackHero
, SupportHero
these three.
After completing this transformation, we will find that TankHero
, AttackHero
, SupportHero
these three categories start to report errors, the specific errors are as follows:
sealed, non-sealed or final modifiers expected
sealed
父类Hero被---bd8475a414ea08e3a96714048f7f45a6---修饰之后, sealed
43f3a99d51b17518b3bbc34de609a938---的密封要求被传递过来,此时子类就必须sealed
、 non-sealed
Choose a definition between non-sealed
, final
, which represent:
-
sealed
: Continue to continue the sealed class feature, you can continue to specify the inherited class, and pass the sealed definition to the subclass -
non-sealed
: Declare this class as an unsealed class, which can be inherited arbitrarily -
final
: inheritance not allowed
According to the above assumptions, the first and second layers are stable, allowing the specific hero roles of the third layer to continuously add new heroes in the later period, so the definitions of the three types of abstract heroes can be written as follows:
public non-sealed class TankHero extends Hero {
}
For the hero role of the third layer, which is already the final specific implementation, you can use the final definition to block the subsequent inheritance relationship, such as this:
public final class Ezreal extends AttackHero {
}
Through this setting, the first and second layers of the three-layer hero's structure are well protected.
Well, today's sharing is here! If you encounter difficulties in the learning process? You can join our high-quality technical exchange group , participate in exchanges and discussions, and learn and progress better! Also, don't walk away, follow me! Continue to update the new Java feature column , see the new Java features in document form, and read and learn better!
Welcome to my public account: Programmer DD. Learn about cutting-edge industry news for the first time, share in-depth technical dry goods, and obtain high-quality learning resources
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。