javajava-17sealed

How to check if a class is explicitly non-sealed?


Is it possible to check if a class is explicitly marked as non-sealed like with MyClass.class.isSealed() and without checking its parent hierarchy? (And if so, how?)

Reason - I want to know if the info is somewhere in the class itself and not guess by checking if its final and looking up the parents. Maybe the language changes one day and this indirect condition may too.


Solution

  • There is, unfortunately, no dedicated method to find out whether a given class is explicitly defined as non-sealed and negating the result of isSealed method does not give you an accurate answer.

    If you know the rules of defining a class as non-sealed, you can construct the method that would do it for you.

    You don't need to check the whole parent hierarchy but due to the definition of non-sealed, you have to inspect its direct supertype (or supertypes in case of 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());
    }
    

    In a small test, only Reptile and Cat are and should be found non-sealed:

    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));
    });