Wednesday, July 26, 2023

Quiz yourself: Java’s sealed types—true-or-false quiz

Oracle Java, Java Certification, Java Guides, Java Learning, Java Tutorial and Materials

Test your knowledge of valid sealed classes, subclasses, and the permits section.

Which statement is true? Choose one.

A. A sealed type declaration must have a permits section.

B.  A sealed class must have at least one direct subclass.

C. A sealed interface must have at least one direct implementation.

D. A sealed type can be an enum.

E. A sealed type can be a record.

Answer. The goal of a sealed type hierarchy is to have source-level specifications that make it very clear what types are permitted to be assignment-compatible with a given base type.

Clearly, even if you don’t have a sealed type hierarchy, you can find this information if you search all the source files used in your codebase. However, that’s laborious at best, and it’s impractical if you have libraries that came from other teams—or from third parties.

As a broad overview, the sealed type mechanism allows the source for one type to explicitly enumerate all its permitted subtypes. Each of those subtypes in turn is subject to restrictions that are generally intended to keep the entire tree clearly visible from the source code.

One possibility is that a subtype is final (either explicitly or implicitly, which is the case with a record type). In this case, you’ve reached the end of the type hierarchy on this branch of the tree.

Another possibility is to open up the hierarchy and allow arbitrary subtypes. This, to an extent, spoils the point of a sealed hierarchy, but it is permitted because practical considerations might warrant it. This is achieved by marking the type as non-sealed.

A third possibility is that the subtype is an enum. An enum can never be named in an extends clause, which means that the sealed parent type must be an interface. Also, subtypes of an enum can exist only when they are declared as inner classes. As inner classes, they’re in the source code of the enum itself, which makes it very clear what, if any, subtypes exist under this branch of the type tree.

The final option is for the subtype itself to be marked as sealed. In this case, its children can be expressly listed. Also in this case, the subtypes’ children are subject to these rules. Once again, it’s very clear from the source which subtypes are possible.

While it’s usual for a sealed type to enumerate its permitted children with permits, there is one situation in which this can be omitted (note that permits is mandatory otherwise). That situation is when all the child types are declared in the same source file (or compilation unit) as the parent type. This includes the possibility of those types being inner or nested classes within the parent type.

This last possibility tells you that option A is incorrect.

The description above omitted an important detail: The purpose of a sealed type hierarchy is to enumerate clearly the permitted child types. If you want zero children of a given type, that class should be marked as final (and, of course, it must be a concrete class). A sealed type must have at least one subtype. This tells you that option B is correct.

Option C is incorrect. Any sealed type must have some child type, but it’s not necessary for an interface to have a direct implementation; it’s perfectly acceptable for it to have a subinterface. Note that an interface cannot be marked as final, so a subinterface of a sealed interface must be either sealed or non-sealed to be valid.

Although an enum cannot be marked as final, a subtype of an enum must be an inner class. This already makes for tight control of the types that can ever be assignment-compatible with it. Of course, this is why an enum can be declared on a sealed type hierarchy without being labeled either sealed, non-sealed, or final. As noted earlier, the sealed parent type of an enum must be an interface. It’s not useful—and is, in fact, not permitted—for an enum type to be marked as sealed. Hence, option D is incorrect.

Record types are implicitly final; hence, they cannot permit subtypes. You know from the discussion related to option B that at least one subclass is mandatory, so you can deduce that option E is also incorrect.

Don’t forget that it’s entirely correct for a record type to appear in a sealed type hierarchy; it simply must be a leaf node, not the root of the hierarchy. It’s also worth observing that since a record type cannot declare a parent class, all the parent types of a record in a sealed hierarchy, up to and including the root of that hierarchy, must be interfaces.

Conclusion. The correct answer is option B.

Source: oracle.com

Related Posts

0 comments:

Post a Comment