RFR: JDK-8322878: Including sealing information Class.toGenericString() [v2]

Joe Darcy darcy at openjdk.org
Mon Jan 8 22:33:52 UTC 2024


On Wed, 3 Jan 2024 19:44:51 GMT, Pavel Rappo <prappo at openjdk.org> wrote:

>> I think the best place, or least-bad place, to discuss the "modifier" ordering of sealed/non-sealed would be an informative note on Modifier.toString(int) -- "The sealed/non-sealed Java language modifiers are not represented in the class file as access flags and thus not modeled by this class [java.lang.reflect.Modifier] .... sealed/non-sealed should be presented in the same location as final."
>> 
>> Since it doesn't seem possible to do so, I did not attempt to relay "non-sealed" information in this PR :-)
>
>> Since it doesn't seem possible to do so, I did not attempt to relay "non-sealed" information in this PR :-)
> 
> Naively, I thought that something like this is possible _in principle_; I might be mistaken though:
> 
> diff --git a/src/java.base/share/classes/java/lang/Class.java b/src/java.base/share/classes/java/lang/Class.java
> index 851d65d06ad..014845860d0 100644
> --- a/src/java.base/share/classes/java/lang/Class.java
> +++ b/src/java.base/share/classes/java/lang/Class.java
> @@ -4771,6 +4771,30 @@ public boolean isSealed() {
>          return getPermittedSubclasses() != null;
>      }
>  
> +    private boolean isNonSealed() {
> +        if (isSealed())
> +            return false;
> +        if (!isInterface() && Modifier.isFinal(getModifiers())) {
> +            // unlike interface, class can be final
> +            return false;
> +        }
> +        // if an ancestor is sealed, this class can either be non-sealed or final
> +        return hasSealedAncestor(this);
> +    }
> +
> +    private boolean hasSealedAncestor(Class<?> clazz) {
> +        var superclass = clazz.getSuperclass();
> +        if (superclass != null) {
> +            if (superclass.isSealed() || hasSealedAncestor(superclass))
> +                return true;
> +        }
> +        for (var superinterface : clazz.getInterfaces()) {
> +            if (superinterface.isSealed() || hasSealedAncestor(superinterface))
> +                return true;
> +        }
> +        return false;
> +    }
> +
>      private native Class<?>[] getPermittedSubclasses0();
>  
>      /*

> Thanks @pavelrappo; I'll explore incorporating functionality like this into the PR, probably next week.

Pushed an initial cut of non-sealing support; will add more test cases later.

-------------

PR Review Comment: https://git.openjdk.org/jdk/pull/17239#discussion_r1445420505


More information about the core-libs-dev mailing list