From james.laskey at oracle.com Thu Jul 5 20:11:43 2018
From: james.laskey at oracle.com (Jim Laskey)
Date: Thu, 5 Jul 2018 17:11:43 -0300
Subject: Targeting JEP 326: Raw String Literal for JDK 12
Message-ID: <0B907300-0238-4D6C-A559-AF8BB4E20E27@oracle.com>
With your guidance, we consider the Raw String Literal design and initial implementation has stabilized enough to target JEP 326 as a Preview Language Feature in JDK 12. Before we proceed, we?d like review some of recommendations made since JEP 326 was proposed as Candidate.
Margin Management
Considerable time was spent discussing how to deal with incidental indentation introduced when a Raw String Literal?s visible content marshals with surrounding code. Clearly, there is no all satisfying solution. We would be remiss if we were to lock the language into a irreversible decision that we may regret in the future. Therefore, the sensible/responsible thing to do is to follow the "raw means raw" principle and leave the Raw String Literal content uninterpreted (other than line terminators) by the compiler, and place the margin management onus on library and developer furnished methods.
To provide incidental indentation support for what we think will be the common case, the following instance method will be added to the String class:
public String align()
which after removing all leading and trailing blank lines, left justifies each line without loss of relative indentation. Thus, stripping away all incidental indentation and line spacing.
Example:
String html = `
Hello World.
`.align();
System.out.print(html);
Output:
Hello World.&
Further, generalized control of indentation will be provided with the following String instance method:
public String indent(int n)
where `n` specifies the number of white spaces to add or remove from each line of the string; a positive `n` adds n spaces (U+0020) and negative `n` removes n white spaces.
Example:
String html = `
Hello World.
`.align().indent(4);
System.out.print(html);
Output:
Hello World.&
In the cases where align() is not what the developer wants, we expect the preponderance of cases to be align().ident(n). Therefore, an additional variation of `align` will be provided:
public align(int n)
where `n` is the indentation applied to the string after _alignment_.
Example:
String html = `
Hello World.
`.align(4);
System.out.print(html);
Output:
Hello World.&
Customizable margin management (and more) will be provided by the string instance method:
R transform?(Function f)
where the supplied function f is called with the string.
Example:
public class MyClass {
private static final String MARGIN_MARKER= "| ";
public String stripMargin(String string) {
return lines().map(String::strip)
.map(s -> s.startsWith(MARGIN_MARKER) ? s.substring(MARGIN_MARKER.length()) : s)
.collect(Collectors.joining("\n", "", "\n"));
}
String stripped = `
| The content of
| the string
`.transform(MyClass::stripMargin);
Output:
The content of
the string
It should be noted that concern for class file size and runtime impact are addressed by the _constant folding_ features of [JEP 303](http://openjdk.java.net/jeps/303 ).
White Space and Tabs
The use of tabs came up during the Margin Management discussion. Specifically, what do tabs represent when removing incidental indentation. As long as the source was consistent across all lines of a multi-line string (with respect to tabs), the align() method will behave as expected. For the cases where it does not, there is no consistent rule for handling it; the best thing to do here is to provide tools for getting back to consistency.
For example, we propose the introduction of String instance method:
public String detab(int n)
which replaces tab U+0009 characters with enough space U+0020 characters to align to tab stops at intervals n, and:
public String entab(int n)
which replaces some space U+0020 characters with tab U+0009 characters if can align to tab stops at intervals n.
Example:
String html = `
Hello World.
`.detab(8).align(4);
System.out.print(html);
Output:
Hello World.&
Escape Sequences
After the initial release of JEP 326 there was some discussion about the names of the escape sequence managing methods. We reversed the naming (unescape/escape), but the lack of additional feedback left us wondering, ?Do we have the appropriate names?? and ?Do we really need these methods??
If these methods are needed rarely, would longer names escapeSequencesToChars and charsToEscapeSequences be more suitable?
Would more putting effort into a more generalized String::replaceAll(Pattern pattern, Function replacer)) make more sense?
Repeating Delimiters
We remain convinced that the choice of an arbitrary sequence of backticks as a delimiter is the best choice. There were two main points of concern; the lack of empty string and the distinction between single & multi-line literals. We contend both of these points are aesthetic and if were part of the design, would take away from the simplicity.
With regards to empty Raw String Literal. Java already has a representation for empty string; ??. Why have two? Raw String Literals do not have to be symmetrically in sync with traditional strings. The lack of symmetry is a discerning plus for Raw String Literal.
With regards to distinction between single & multi-line literals. If the developer chooses to use single backticks for single line and triple backticks for multi-line there is nothing in the design that prevents the developer from doing so. However, we would discourage the adoption of this "coding convention".
Cheers,
- Jim
From guy.steele at oracle.com Thu Jul 5 20:37:35 2018
From: guy.steele at oracle.com (Guy Steele)
Date: Thu, 5 Jul 2018 16:37:35 -0400
Subject: Targeting JEP 326: Raw String Literal for JDK 12
In-Reply-To: <0B907300-0238-4D6C-A559-AF8BB4E20E27@oracle.com>
References: <0B907300-0238-4D6C-A559-AF8BB4E20E27@oracle.com>
Message-ID:
> On Jul 5, 2018, at 4:11 PM, Jim Laskey wrote:
>
> With your guidance, we consider the Raw String Literal design and initial implementation has stabilized enough to target JEP 326 as a Preview Language Feature in JDK 12. Before we proceed, we?d like review some of recommendations made since JEP 326 was proposed as Candidate.
> . . .
A warning: not all of the given ?Output? examples have exactly the correct number of leading spaces on all lines. In the example for ?align()?, for example, what is shown is:
Example:
String html = `
Hello World.
`.align();
System.out.print(html);
Output:
Hello World.&
but I believe the correct output would be:
Output:
Hello World.&
That is, each of the middle three lines of output needed to have an additional leading space character.
Otherwise everything in the email looked okay to me.
?Gy
From james.laskey at oracle.com Thu Jul 5 21:05:51 2018
From: james.laskey at oracle.com (James Laskey)
Date: Thu, 5 Jul 2018 18:05:51 -0300
Subject: Targeting JEP 326: Raw String Literal for JDK 12
In-Reply-To:
References: <0B907300-0238-4D6C-A559-AF8BB4E20E27@oracle.com>
Message-ID: <00737357-8E9F-4CA7-B69D-8A321D8E373C@oracle.com>
You are correct. I thought I caught all the stray cases, but... The examples should have indentations that are multiples of 4. The issue with pasting from IDEs to mailers.
Sent from my iPhone
> On Jul 5, 2018, at 5:37 PM, Guy Steele wrote:
>
>
>> On Jul 5, 2018, at 4:11 PM, Jim Laskey wrote:
>>
>> With your guidance, we consider the Raw String Literal design and initial implementation has stabilized enough to target JEP 326 as a Preview Language Feature in JDK 12. Before we proceed, we?d like review some of recommendations made since JEP 326 was proposed as Candidate.
>> . . .
>
>
> A warning: not all of the given ?Output? examples have exactly the correct number of leading spaces on all lines. In the example for ?align()?, for example, what is shown is:
>
> Example:
>
> String html = `
>
>
> Hello World.
>
>
> `.align();
> System.out.print(html);
>
> Output:
>
>
> Hello World.&
>
>
>
> but I believe the correct output would be:
>
> Output:
>
>
> Hello World.&
>
>
>
> That is, each of the middle three lines of output needed to have an additional leading space character.
>
> Otherwise everything in the email looked okay to me.
>
> ?Gy
>
>
>
From daniel.smith at oracle.com Fri Jul 6 22:26:39 2018
From: daniel.smith at oracle.com (Dan Smith)
Date: Fri, 6 Jul 2018 16:26:39 -0600
Subject: [RSL] RSL update
In-Reply-To: <059fe719-1374-a013-571a-7b4a357012e9@oracle.com>
References:
<059fe719-1374-a013-571a-7b4a357012e9@oracle.com>
Message-ID:
> On Jun 26, 2018, at 6:09 AM, Brian Goetz wrote:
>
>
>> Here are two more arguments in favor of language-level stripping:
>>
>> 1. Strings inside annotations aren't left out. Whenever an annotation attribute feels like something users may want to use an RSL for, the best we can hope for (if we don't have automatic unindenting) is for the specification of that attribute to say "consumers of this data really should call .align() on this" - quite unsatisfying, and we can be sure most annotation specs won't bother.
>
> This seems like a pretty corner^3 case to me; long strings in annotations are kind of questionable already, multi-line strings in an annotation seem even more so, and in those cases where you absolutely need to be divorced from the incidental indentation, you could just align it yourself correctly, at the cost of uglier indentation (or pull it out into a static var.)
Just to be clear about dependencies: "pull it out into a static var" only works if the 'align' call is a constant expression. Which it ought to be, yes, but that's a separate feature we'll need to deliver.
(And really ought to, I think. Otherwise, if we anticipate some releases in which 'align' calls disrupt what would otherwise be constant expressions, that's a notable argument in favor of the language approach.)
From forax at univ-mlv.fr Mon Jul 9 06:39:42 2018
From: forax at univ-mlv.fr (Remi Forax)
Date: Mon, 9 Jul 2018 08:39:42 +0200 (CEST)
Subject: Extending 15.28 to include toString() on an enum constant
Message-ID: <73648976.40631.1531118382273.JavaMail.zimbra@u-pem.fr>
[this was sent to the amber-spec-comment]
Hi Daniel,
----- Mail original -----
> De: "Daniel Trebbien"
> ?: "amber-spec-comments"
> Envoy?: Lundi 9 Juillet 2018 02:43:00
> Objet: Extending 15.28 to include toString() on an enum constant
> One small idea I have for enhancing the Java language is to allow
> toString() on enum constants to be used in constant expressions, as long as
> toString()
>
> is not overidden, or if it is, the implementation returns a constant
> expression.
>
> There are two use cases I have in mind for this:
>
> 1. When using the SLF4J logging library, if you want to embed the name of
> an enum constant in the log message, you should use parameterized logging
> to avoid incurring a wasted runtime string concatenation if logging at the
> specified level is disabled. See SLF4J's FAQ for "What is the fastest way
> of (not) logging?": https://www.slf4j.org/faq.html#logging_performance
> As an example of this in the wild, I submitted a pull request in which I
> converted a log statement involving an enum constant to parameterized
> logging:
> https://github.com/Netflix/eureka/commit/ad81a1140f351ec19165cb94d5aa668cfc08a932
> There are other cases where an SLF4J logger call involving an enum constant
> correctly used parameterized logging, but I am not able to find an example
> right now.
SLF4J should offer to have a lambda as parameter (as log4j2 does), parameterized logging solve the problem of the cost when not logging but at the cost of slowing down the logging when the logger logs because it has to do string interpolation.
>
> Although using parameterized logging solves the performance issue, it is
> desirable to keep down the number of parameters to an SLF4J logger call
> because the SLF4J Logger interface
> has more efficient
> variants of the trace(), debug(), info(), warn(), and error() calls that
> take zero, exactly one, and exactly two parameters. If a logger call
> passes at most two parameters, then the construction of an Object array to
> package the parameters into varargs is avoided. Needing to "waste" a
> parameter slot on an enum constant is undesirable.
>
> 2. When using Spring Security, it is possible to define an enum that lists
> the roles and other categories of permissions that are used by a Spring
> application. For example:
>
> package com.myapp.security;
>
> import org.springframework.security.core.GrantedAuthority;
>
> public enum AppAuthority implements GrantedAuthority {
>
> ROLE_USER,
> ROLE_ADMINISTRATOR;
>
> @Override
> public String getAuthority() {
> return toString();
> }
> }
>
> When using the org.springframework.security.access.annotation.Secured
>
> annotation to secure controllers or actions, it would be nice to be able to
> use an enum constant in the annotation's value, as in @Secured({
> ROLE_ADMINISTRATOR.toString() }); however, this is currently not valid Java
> code because ROLE_ADMINISTRATOR.toString() is not a constant expression.
> Instead, the name of the role must be duplicated: @Secured({ "
> ROLE_ADMINISTRATER" }). This is undesirable because it is error-prone and
> makes refactoring more difficult. It is also more difficult to find usages
> of a particular authority. If toString() on an enum constant were allowed
> within a constant expression, then finding usages of a particular authority
> would be a "Find Usages" operation in an IDE.
JEP 303 (http://openjdk.java.net/jeps/303) allows to build such kind of constants, i don't know if it works in the context of annotations but it's a nice use case.
The other solution is to allow any expressions in a annotation context and let the compiler emit a Constant_Dynamic that will be initialized with that expression, this solution has the advantage over the JEP 303 of not evaluating the expression by the compiler but at runtime by the VM, meaning that if there is a bug in toString() or in any calls inside of the expression, you do not have to re-compile the code. As a war story, a friend of mine has exactly the same issue with a Kotlin function which checks some credential and is marked inline there was a bug in it, so he rolls a security fix only to see that the bug was still appearing sometimes because he had to recompile all the codes that were using that function too.
regards,
R?mi
From maurizio.cimadamore at oracle.com Mon Jul 9 08:52:11 2018
From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore)
Date: Mon, 9 Jul 2018 09:52:11 +0100
Subject: Extending 15.28 to include toString() on an enum constant
In-Reply-To: <73648976.40631.1531118382273.JavaMail.zimbra@u-pem.fr>
References: <73648976.40631.1531118382273.JavaMail.zimbra@u-pem.fr>
Message-ID:
Remi is correct - 303 has the potential to special case toString()
method calls on enums. One thing that 303 lacks, at least at the moment,
is the ability to redefine what goes into places where a constant
expression is expected (case labels, annotations, ...). That is, the
additional constant propagation occurs *after* type-checking, and it's
mostly there to support code generation. What you ask would have an
impact on the language frontend (and would therefore require some spec
text for it) - I'm unsure as to whether this falls within the scope of 303.
Maurizio
On 09/07/18 07:39, Remi Forax wrote:
> JEP 303 (http://openjdk.java.net/jeps/303) allows to build such kind of constants, i don't know if it works in the context of annotations but it's a nice use case.
From brian.goetz at oracle.com Mon Jul 9 12:55:39 2018
From: brian.goetz at oracle.com (Brian Goetz)
Date: Mon, 9 Jul 2018 08:55:39 -0400
Subject: Fwd: Extending 15.28 to include toString() on an enum constant
In-Reply-To:
References:
Message-ID: <57aa3237-3466-df7e-2603-5528e0bba21f@oracle.com>
The following was received on the -comments list.
Here's my thoughts on this.
This is a prime example of the sort of language feature that could be
described as "opening a fresh can of worms."? In addition to increasing
the complexity of the language by adding a narrow and esoteric
irregularity (special treatment for toString()), it would surely be the
case that tomorrow, there would be a long line of similar irregularities
queueing up to demand equal treatment.
But, the problems you cite are real concerns, so let's talk about those,
rather than the specific solution.? The first observes how non-logging
of constants is less expensive than non-logging of non-constants.? As an
example, you cite this change:
-??????????? logger.info("Datacenter is: " + DataCenterInfo.Name.Amazon);
+??????????? logger.info("Datacenter is: {}", DataCenterInfo.Name.Amazon);
There are other common ways to handle this in logging frameworks. One is
to pass a lambda instead of arguments; another is to unroll the constant
yourself:
+??????????? logger.info("Datacenter is: AMAZON");
Logging is a bit of a special case, since in few other APIs do you
regularly pass expressions that most of the time you wish would not
actually be evaluated.? And I would suggest that this sort of
almost-but-not-quite-foldable string concatenation is a relatively rare
case.? So I'm not really seeing this as a big motivation for an
irregular change.
That said, there are some other operations that are far more deserving
of better compile-time treatment.? In the context of raw string
literals, we expect the `align()` call to be common; given that
`align()` is pure, evaluating it at compile time rather than run time
will be a big win.? You should expect to see this sort of thing coming
out of JEP 303.? (Though I doubt it would go as far as `toString()` on
enums, because at compile time, we cannot prove that _at run time_
`toString()` would not have been overridden.? Constant-folding of static
methods is far less problematic than for virtual methods.)
You raised a second case: constants in annotations.? This is very
different in character from the first case.? The first case is a pure
quest-for-performance; hoping that the compile/runtime can optimize
something better.? The second is looking for language changes to make
annotations more expressive; extending the notion of "constant
expression" so more expressions can be used as annotation parameters.?
We've actually thought about this quite a bit in the context of JEP 303.
My conclusion is: this would be a bad idea.? It's great if the compiler
can opportunistically spot opportunities to eliminate computation, but
tying the semantics of a high-level language construct to this is pretty
dangerous.? It means that in order to correctly reason about what can go
in an annotation, every developer must be able to correctly reason about
all the optimizations a compiler might do -- which is clearly a recipe
for frustration and confusion.
Additionally, I thing the resulting language is not one we'll want to
program in.? When you pull this string to the end, you will end up with
complex mini-programs as parameters to annotations.? But annotations are
for metadata, not carriers for mini-programs.
(We also confronted this from another angle; it has recently become
practical to allow putting (non-bound) method references in annotations,
which is a reasonable fit for the role of annotations.? But the obvious
next question is: what about lambdas?? And while the machinery is the
same, this is almost certainly over the line -- do we really want
annotations stuffed full with little mini-method bodies (or, not so mini)?)
-------- Forwarded Message --------
Subject: Extending 15.28 to include toString() on an enum constant
Date: Sun, 8 Jul 2018 20:43:00 -0400
From: Daniel Trebbien
To: amber-spec-comments at openjdk.java.net
One small idea I have for enhancing the Java language is to allow
toString() on enum constants to be used in constant expressions, as long as
toString()
is not overidden, or if it is, the implementation returns a constant
expression.
There are two use cases I have in mind for this:
1. When using the SLF4J logging library, if you want to embed the name of
an enum constant in the log message, you should use parameterized logging
to avoid incurring a wasted runtime string concatenation if logging at the
specified level is disabled. See SLF4J's FAQ for "What is the fastest way
of (not) logging?": https://www.slf4j.org/faq.html#logging_performance
As an example of this in the wild, I submitted a pull request in which I
converted a log statement involving an enum constant to parameterized
logging:
https://github.com/Netflix/eureka/commit/ad81a1140f351ec19165cb94d5aa668cfc08a932
There are other cases where an SLF4J logger call involving an enum constant
correctly used parameterized logging, but I am not able to find an example
right now.
Although using parameterized logging solves the performance issue, it is
desirable to keep down the number of parameters to an SLF4J logger call
because the SLF4J Logger interface
has more efficient
variants of the trace(), debug(), info(), warn(), and error() calls that
take zero, exactly one, and exactly two parameters. If a logger call
passes at most two parameters, then the construction of an Object array to
package the parameters into varargs is avoided. Needing to "waste" a
parameter slot on an enum constant is undesirable.
2. When using Spring Security, it is possible to define an enum that lists
the roles and other categories of permissions that are used by a Spring
application. For example:
package com.myapp.security;
import org.springframework.security.core.GrantedAuthority;
public enum AppAuthority implements GrantedAuthority {
ROLE_USER,
ROLE_ADMINISTRATOR;
@Override
public String getAuthority() {
return toString();
}
}
When using the org.springframework.security.access.annotation.Secured
annotation to secure controllers or actions, it would be nice to be able to
use an enum constant in the annotation's value, as in @Secured({
ROLE_ADMINISTRATOR.toString() }); however, this is currently not valid Java
code because ROLE_ADMINISTRATOR.toString() is not a constant expression.
Instead, the name of the role must be duplicated: @Secured({ "
ROLE_ADMINISTRATER" }). This is undesirable because it is error-prone and
makes refactoring more difficult. It is also more difficult to find usages
of a particular authority. If toString() on an enum constant were allowed
within a constant expression, then finding usages of a particular authority
would be a "Find Usages" operation in an IDE.
From brian.goetz at oracle.com Mon Jul 9 13:10:59 2018
From: brian.goetz at oracle.com (Brian Goetz)
Date: Mon, 9 Jul 2018 09:10:59 -0400
Subject: Extending 15.28 to include toString() on an enum constant
In-Reply-To:
References: <73648976.40631.1531118382273.JavaMail.zimbra@u-pem.fr>
Message-ID: <26d97a10-f1d9-6f39-01cc-1a7847c1d17c@oracle.com>
I doubt 303 will ever be able to constant fold a non-final virtual
method in this manner.? Enums can override toString(), and can do so via
separate compilation; this seems like it would be too big of a surprise
to users.? Virtual methods are much riskier to constant fold than static
ones (in part, because it's action-at-a-distance; a declaration modifier
on a supertype causes folding of a method in a subtype.)
On 7/9/2018 4:52 AM, Maurizio Cimadamore wrote:
> Remi is correct - 303 has the potential to special case toString()
> method calls on enums. One thing that 303 lacks, at least at the
> moment, is the ability to redefine what goes into places where a
> constant expression is expected (case labels, annotations, ...). That
> is, the additional constant propagation occurs *after* type-checking,
> and it's mostly there to support code generation. What you ask would
> have an impact on the language frontend (and would therefore require
> some spec text for it) - I'm unsure as to whether this falls within
> the scope of 303.
>
> Maurizio
>
>
> On 09/07/18 07:39, Remi Forax wrote:
>> JEP 303 (http://openjdk.java.net/jeps/303) allows to build such kind
>> of constants, i don't know if it works in the context of annotations
>> but it's a nice use case.
>
From john.r.rose at oracle.com Tue Jul 10 00:19:40 2018
From: john.r.rose at oracle.com (John Rose)
Date: Mon, 9 Jul 2018 17:19:40 -0700
Subject: Extending 15.28 to include toString() on an enum constant
In-Reply-To: <26d97a10-f1d9-6f39-01cc-1a7847c1d17c@oracle.com>
References: <73648976.40631.1531118382273.JavaMail.zimbra@u-pem.fr>
<26d97a10-f1d9-6f39-01cc-1a7847c1d17c@oracle.com>
Message-ID: <9C32988B-1310-4BCF-8CC6-6AA882FE2D89@oracle.com>
On Jul 9, 2018, at 6:10 AM, Brian Goetz wrote:
>
> Virtual methods are much riskier to constant fold than static ones (in part, because it's action-at-a-distance; a declaration modifier on a supertype causes folding of a method in a subtype.)
As a halfway point between general virtuals and statics,
virtuals in final classes or sealed hierarchies are more
like statics than not. The risk of action at a distance is
that the class would be de-finalized or the hierarchy
would be un-sealed, thus turning the virtual API point
into a dynamically resolved method.
Maybe enums could live in the halfway point, since they
are final and/or sealed.
A second problem with virtuals relative to statics is they
are dependent on the receiver type, so for sealed (not final)
classes, the static compiler might not be able to decide
on the concrete type of an operand. That can be special
cased for enums also.
enum Foo { // Foo is sealed; Foo$Bat is final
Bar, Baz, Bat {
public String toString() { return "Bat, actually"; } };
public String toString() { return "a Foo"; }
}
? John
From dtrebbien at gmail.com Tue Jul 10 18:47:09 2018
From: dtrebbien at gmail.com (Daniel Trebbien)
Date: Tue, 10 Jul 2018 14:47:09 -0400
Subject: Extending 15.28 to include toString() on an enum constant
In-Reply-To: <57aa3237-3466-df7e-2603-5528e0bba21f@oracle.com>
References:
<57aa3237-3466-df7e-2603-5528e0bba21f@oracle.com>
Message-ID:
On Mon, Jul 9, 2018 at 8:55 AM, Brian Goetz wrote:
...
> That said, there are some other operations that are far more deserving of
> better compile-time treatment. In the context of raw string literals, we
> expect the `align()` call to be common; given that `align()` is pure,
> evaluating it at compile time rather than run time will be a big win. You
> should expect to see this sort of thing coming out of JEP 303. (Though I
> doubt it would go as far as `toString()` on enums, because at compile time,
> we cannot prove that _at run time_ `toString()` would not have been
> overridden. Constant-folding of static methods is far less problematic
> than for virtual methods.)
>
>
> You raised a second case: constants in annotations. This is very
> different in character from the first case. The first case is a pure
> quest-for-performance; hoping that the compile/runtime can optimize
> something better. The second is looking for language changes to make
> annotations more expressive; extending the notion of "constant expression"
> so more expressions can be used as annotation parameters. We've actually
> thought about this quite a bit in the context of JEP 303.
>
> My conclusion is: this would be a bad idea. It's great if the compiler
> can opportunistically spot opportunities to eliminate computation, but
> tying the semantics of a high-level language construct to this is pretty
> dangerous. It means that in order to correctly reason about what can go in
> an annotation, every developer must be able to correctly reason about all
> the optimizations a compiler might do -- which is clearly a recipe for
> frustration and confusion.
>
> Additionally, I thing the resulting language is not one we'll want to
> program in. When you pull this string to the end, you will end up with
> complex mini-programs as parameters to annotations. But annotations are
> for metadata, not carriers for mini-programs.
>
> (We also confronted this from another angle; it has recently become
> practical to allow putting (non-bound) method references in annotations,
> which is a reasonable fit for the role of annotations. But the obvious
> next question is: what about lambdas? And while the machinery is the same,
> this is almost certainly over the line -- do we really want annotations
> stuffed full with little mini-method bodies (or, not so mini)?)
>
That's a good point about the toString() implementation changing between
compilations. If a class SomeController is compiled against an AppAuthority
enum whose toString() implementation returns "something", and then the enum
is recompiled with a different toString() implementation that returns
"something_else", then the first compilation of SomeController is
outdated. In such a scenario, it would be useful to have some sort of
runtime error diagnostic, but this, I think, would be the start of a One
Definition Rule in Java which probably isn't a great idea.
Could JEP 303 cover Enum#name()
,
since it's non-overridable? Maybe name() could then be used within
constant expressions.
One difficulty with allowing name() to be used in constant expressions is
providing a diagnostic if the enum is recompiled to remove an enum constant
that was inlined into a constant expression in some other compilation
unit. By way of example, suppose we have AdminController as follows:
@Controller
@RequestMapping("/admin")
@Secured({ AppAuthority.ROLE_ADMINISTRATOR.name() })
public class AdminController {
//...
}
.. and then AppAuthority is modified to remove the ROLE_ADMINISTRATOR enum
constant. In such a scenario, I think that there should be some sort of
LinkageError thrown when the AdminController class is loaded by the JVM.