<!DOCTYPE html><html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  </head>
  <body>
    <p>Hello,</p>
    <p>Some time back, the java.lang.reflect package level docs had a
      brief discussion added concerning what exactly core reflection is
      modeling. [1]. tl;dr -- mostly a class file level view. As such, a
      contingent property of the design of JEP 409 is that
      sealed/non-sealed happens to _not_ to expressed JVM-level access
      flags/modifiers. However, it would be reasonable IMO for
      Class.toGenericString(), but not Class.toString(), to be updated
      to expose some sealing-related information. I've filed
      JDK-8322878: "Including sealing information
      Class.toGenericString()."<br>
    </p>
    <p>-Joe</p>
    <p>[1] Added under     JDK-8262807: "Note assumptions of core
      reflection modeling and parameter handling" in JDK 17:<br>
    </p>
    <p>
      <blockquote type="cite">Java programming language and JVM modeling
        in core reflection <br>
        <br>
        The components of core reflection, which include types in this
        package as well as Class, Package, and Module, fundamentally
        present a JVM model of the entities in question rather than a
        Java programming language model. A Java compiler, such as javac,
        translates Java source code into executable output that can be
        run on a JVM, primarily class files. Compilers for source
        languages other than Java can and do target the JVM as well.<br>
        <br>
        The translation process, including from Java language sources,
        to executable output for the JVM is not a one-to-one mapping.
        Structures present in the source language may have no
        representation in the output and structures not present in the
        source language may be present in the output. The latter are
        called synthetic structures. Synthetic structures can include
        methods, fields, parameters, classes and interfaces. One
        particular kind of synthetic method is a bridge method. It is
        possible a synthetic structure may not be marked as such. In
        particular, not all class file versions support marking a
        parameter as synthetic. A source language compiler generally has
        multiple ways to translate a source program into a class file
        representation. The translation may also depend on the version
        of the class file format being targeted as different class file
        versions have different capabilities and features. In some cases
        the modifiers present in the class file representation may
        differ from the modifiers on the originating element in the
        source language, including final on a parameter and protected,
        private, and static on classes and interfaces.<br>
        <br>
        Besides differences in structural representation between the
        source language and the JVM representation, core reflection also
        exposes runtime specific information. For example, the class
        loaders and protection domains of a Class are runtime concepts
        without a direct analogue in source code.</blockquote>
      <br>
    </p>
    <p><a class="moz-txt-link-freetext" href="https://download.java.net/java/early_access/jdk23/docs/api/java.base/java/lang/reflect/package-summary.html">https://download.java.net/java/early_access/jdk23/docs/api/java.base/java/lang/reflect/package-summary.html</a><br>
    </p>
    <div class="moz-cite-prefix">On 1/2/2024 8:56 AM, Roger Riggs wrote:<br>
    </div>
    <blockquote type="cite" cite="mid:24710123-fde3-4412-b2a7-e5981a713ba6@oracle.com">
      
      Hi Pavel,<br>
      <br>
      It better to look to <a href="https://docs.oracle.com/en/java/javase/21/docs/api/java.compiler/javax/lang/model/element/Modifier.html" moz-do-not-send="true">javax.lang.model.element.Modifier</a> for
      the language view of the class.<br>
      <br>
      java.lang.reflect.Modifier covers the modifier flags as
      represented in the class file and defined in the JVMS.<br>
      <div style="background-color:#ffffff;color:#080808">
        <pre style="font-family:'JetBrains Mono',monospace;font-size:10.5pt;"><span style="color:#8c8c8c;font-style:italic;">* The values for the constants
</span><span style="color:#8c8c8c;font-style:italic;">* representing the modifiers are taken from the tables in sections
</span><span style="color:#8c8c8c;font-style:italic;">* {@jvms 4.1}, {@jvms 4.4}, {@jvms 4.5}, and {@jvms 4.7} of
</span><span style="color:#8c8c8c;font-style:italic;">* </span><span style="color:#8c8c8c;background-color:#e2ffe2;font-style:italic;"><cite></span><span style="color:#8c8c8c;font-style:italic;">The Java Virtual Machine Specification</span><span style="color:#8c8c8c;background-color:#e2ffe2;font-style:italic;"></cite></span><span style="color:#8c8c8c;font-style:italic;">.</span></pre>
      </div>
      Sealing is represented in the class file as a non-empty list of
      permitted classes. Hence the method of java.lang.Class.<br>
      <br>
      Since java.lang.Modifier.toString is based on the flag bits from
      the class file, "sealed" would not appear in any string it
      generates.<br>
      <br>
      <br>
      It might be possible to inject a comment in the toString method
      similar to the comment about interface not being a true modifier
      and including a reference to the javax.lang.model.element.Modifier
      enum.<br>
      <br>
      Roger<br>
      <br>
      <br>
      <div class="moz-cite-prefix">On 1/2/24 11:31 AM, Pavel Rappo
        wrote:<br>
      </div>
      <blockquote type="cite" cite="mid:355BA0BB-4543-4598-BFE1-09984CF8D2EE@oracle.com">
        <pre class="moz-quote-pre" wrap="">Hi Roger,

Happy New Year to you too!

Although it's a _somewhat_ separate issue, I found that the shell script refers to java.lang.reflect.Modifier#toString which does NOT mention either `sealed` or `non-sealed`. More precisely, the script refers to the JDK 8 version of that method, but [the method](<a class="moz-txt-link-freetext" href="https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/lang/reflect/Modifier.html#toString(int))" moz-do-not-send="true">https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/lang/reflect/Modifier.html#toString(int))</a> hasn't changed since 2009 and states that:

    ...The modifier names are returned in an order consistent with the suggested modifier orderings given in sections 8.1.1, 8.3.1, 8.4.3, 8.8.3, and 9.1.1 of The Java Language Specification. The full modifier ordering used by this method is:

    public protected private abstract static final transient volatile synchronized native strictfp interface

It does not seem like `sealed` and `non-sealed` are even modelled by java.lang.reflect.Modifier, although `sealed` is modelled by `java.lang.Class#isSealed`. It cannot be overlook, can it?

</pre>
        <blockquote type="cite">
          <pre class="moz-quote-pre" wrap="">On 2 Jan 2024, at 14:38, Roger Riggs <a class="moz-txt-link-rfc2396E" href="mailto:roger.riggs@oracle.com" moz-do-not-send="true"><roger.riggs@oracle.com></a> wrote:

Hi Pavel,

yes, a PR would be next.

Happy New Year, Roger

On 1/2/24 7:08 AM, Pavel Rappo wrote:
</pre>
          <blockquote type="cite">
            <pre class="moz-quote-pre" wrap="">I assume the order for `sealed` and `non-sealed` has effectively been decided by JLS: <a class="moz-txt-link-freetext" href="https://docs.oracle.com/javase/specs/jls/se21/html/jls-8.html#jls-8.1.1" moz-do-not-send="true">https://docs.oracle.com/javase/specs/jls/se21/html/jls-8.html#jls-8.1.1</a>

    8.1.1. Class Modifiers
    ...
         ClassModifier:
    (one of)
    Annotation public protected private
    abstract static final sealed non-sealed strictfp
         ...

    If two or more (distinct) class modifiers appear in a class declaration, then it is customary, though not required, that they appear in the order consistent with that shown above in the production for ClassModifier.


Shall I just create a PR?

</pre>
            <blockquote type="cite">
              <pre class="moz-quote-pre" wrap="">On 2 Jan 2024, at 11:56, Pavel Rappo <a class="moz-txt-link-rfc2396E" href="mailto:pavel.rappo@oracle.com" moz-do-not-send="true"><pavel.rappo@oracle.com></a> wrote:

I couldn't find any prior discussions on this matter.

I noticed that bin/blessed-modifier-order.sh has not been updated for the [recently introduced](<a class="moz-txt-link-freetext" href="https://openjdk.org/jeps/409" moz-do-not-send="true">https://openjdk.org/jeps/409</a>) `sealed` and `non-sealed` keywords. I also note that we already have cases in OpenJDK where those keywords are ordered differently. If we have a consensus on how to extend the "blessed order" onto those new keywords, I can create a PR to update the script.

-Pavel

</pre>
            </blockquote>
          </blockquote>
        </blockquote>
      </blockquote>
      <br>
    </blockquote>
  </body>
</html>