Hello,
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()."
-Joe
[1] Added under JDK-8262807: "Note assumptions of core reflection
modeling and parameter handling" in JDK 17:
Java programming language and JVM modeling in core reflection
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.
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.
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.
https://download.java.net/java/early_access/jdk23/docs/api/java.base/java/lang/reflect/package-summary.html
On 1/2/2024 8:56 AM, Roger Riggs wrote:
Hi Pavel,
It better to look to javax.lang.model.element.Modifier
<https://docs.oracle.com/en/java/javase/21/docs/api/java.compiler/javax/lang/model/element/Modifier.html>
for the language view of the class.
java.lang.reflect.Modifier covers the modifier flags as represented in
the class file and defined in the JVMS.
* The values for the constants * representing the modifiers are taken
from the tables in sections * {@jvms 4.1}, {@jvms 4.4}, {@jvms 4.5},
and {@jvms 4.7} of * <cite>The Java Virtual Machine Specification</cite>.
Sealing is represented in the class file as a non-empty list of
permitted classes. Hence the method of java.lang.Class.
Since java.lang.Modifier.toString is based on the flag bits from the
class file, "sealed" would not appear in any string it generates.
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.
Roger
On 1/2/24 11:31 AM, Pavel Rappo wrote:
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](https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/lang/reflect/Modifier.html#toString(int))
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?
On 2 Jan 2024, at 14:38, Roger Riggs<roger.ri...@oracle.com> wrote:
Hi Pavel,
yes, a PR would be next.
Happy New Year, Roger
On 1/2/24 7:08 AM, Pavel Rappo wrote:
I assume the order for `sealed` and `non-sealed` has effectively been decided
by JLS:https://docs.oracle.com/javase/specs/jls/se21/html/jls-8.html#jls-8.1.1
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?
On 2 Jan 2024, at 11:56, Pavel Rappo<pavel.ra...@oracle.com> 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](https://openjdk.org/jeps/409) `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