不幸的是,目前并没有一个专门的方法可以直接判断给定类是否被明确声明为non-sealed
,并且仅通过否定isSealed
方法的结果并不能得到准确的答案。
如果你了解定义一个类为non-sealed
的规则,你可以编写一个方法来实现这个功能。
- 被检查的
class
/interface
不能 是final
的。
- 被检查的
class
/interface
不能 是sealed
的。
- 如果被检查的类是
class
,其直接父类必须是sealed
的。
- 如果被检查的类是
interface
,其直接超接口之一必须是sealed
的。
你不需要检查整个父类继承结构,但由于non-sealed
的定义,你需要检查它的直接
超类型(或对于interface
的情况下的多个直接超接口)。
private static boolean isNonSealed(Class<?> clazz) {
final boolean extendsSealedInterface = clazz.isInterface() && Arrays.stream(clazz.getInterfaces()).anyMatch(Class::isSealed);
final boolean extendsSealedClass = clazz.getSuperclass() != null && clazz.getSuperclass().isSealed();
return !clazz.isSealed()
&& (extendsSealedInterface || extendsSealedClass)
&& !Modifier.isFinal(clazz.getModifiers());
}
在小型测试中,只有<code>Reptile</code>和<code>Cat</code>被正确识别为<code>non-sealed</code>:
List<Class<?>> classes = List.of(
Animal.class, Mammal.class, Reptile.class,
Dog.class, Cat.class, SiameseCat.class);
classes.forEach(clazz -> {
System.out.printf("%10s : isSealed = %5s, parent.isSealed=%5s, isFinal=%5s -> isNonSealed=%s%n",
clazz.getSimpleName(),
clazz.isSealed(),
clazz.getSuperclass().isSealed(),
Modifier.isFinal(clazz.getModifiers()),
isNonSealed(clazz));
});
下面是相关示例类的定义及运行结果:
类结构:
// 省略了'permits'关键字,因为所有子类都在同一个文件中。
static sealed class Animal {}
static sealed class Mammal extends Animal {}
static non-sealed class Reptile extends Animal {}
static final class Dog extends Mammal {}
static non-sealed class Cat extends Mammal {}
static class SiameseCat extends Cat {}
输出显示,只有<code>Reptile</code>和<code>Cat</code>是非密封的:
Animal : isSealed = true, parent.isSealed=false -> isNonSealed=false
Mammal : isSealed = true, parent.isSealed=true -> isNonSealed=false
Reptile : isSealed = false, parent.isSealed=true -> isNonSealed=true
Dog : isSealed = false, parent.isSealed=true -> isNonSealed=false
Cat : isSealed = false, parent.isSealed=true -> isNonSealed=true
SiameseCat : isSealed = false, parent.isSealed=false -> isNonSealed=false
接口结构:
sealed interface Animal {}
sealed interface Mammal extends Animal {}
non-sealed interface Reptile extends Animal {}
static final class Dog implements Mammal {} // doggo仍然是一个类
non-sealed interface Cat extends Mammal {}
interface SiameseCat extends Cat {}
输出:
Animal : isSealed = true, parent.isSealed=false -> isNonSealed=false
Mammal : isSealed = true, parent.isSealed=true -> isNonSealed=false
Reptile : isSealed = false, parent.isSealed=true -> isNonSealed=true
Dog : isSealed = false, parent.isSealed=true -> isNonSealed=false
Cat : isSealed = false, parent.isSealed=true -> isNonSealed=true
SiameseCat : isSealed = false, parent.isSealed=false -> isNonSealed=false