switch expression with not explicit yield value should work ?
Brian Goetz
brian.goetz at oracle.com
Thu Oct 28 17:48:40 UTC 2021
If all branches throw, then you can refactor
switch (x) {
case X -> throw e;
...
}
to
throw switch (x) {
case X -> e;
}
On 10/28/2021 1:12 PM, forax at univ-mlv.fr wrote:
> I fell in the same trap yet again :(
>
> Am i the only one that want to throw exceptions in all branches of a switch ?
>
> https://github.com/forax/write_your_own_java_framework/blob/master/interceptor/src/test/java/org/github/forax/framework/interceptor/InterceptorRegistryTest.java#L523
>
> Rémi
>
> ----- Original Message -----
>> From: "Tagir Valeev"<amaembo at gmail.com>
>> To: "Remi Forax"<forax at univ-mlv.fr>
>> Cc: "amber-spec-experts"<amber-spec-experts at openjdk.java.net>
>> Sent: Lundi 30 Août 2021 04:00:27
>> Subject: Re: switch expression with not explicit yield value should work ?
>> Hello!
>>
>> I think this is not related to recent JEPs. This behavior is
>> standardised since Java 14 when Switch expression was introduced:
>>
>> // Compilation error
>> int x = switch(0) {
>> default -> throw new IllegalArgumentException();
>> };
>>
>> This is explicitly specified (15.28.1) [1]:
>>
>>> It is a compile-time error if a switch expression has no result expressions.
>> There was some discussion about this rule in March, 2019 [2].
>> Basically, the idea is to preserve the possibility of normal
>> (non-abrupt) execution of every expression.
>> I believe, preventing unreachable code has always been in the spirit
>> of Java. In your code sample, the execution of the 'return' statement
>> itself is unreachable,
>> so writing 'return' is redundant. In my sample above, the 'x' variable
>> is never assigned to anything, and the subsequent statements (if any)
>> are unreachable as well.
>>
>> I'd vote to keep the current behavior. While it may complicate code
>> generation and automatic refactorings, this additional complexity is
>> only marginal. The benefit is
>> that this behavior may save us from accidental mistakes.
>>
>> Btw, you may deceive the compiler introducing a method like
>>
>> static Object fail() {
>> throw new IllegalArgumentException();
>> }
>>
>> And use "case Object __ -> fail()"
>>
>> With best regards,
>> Tagir Valeev.
>>
>> [1]https://docs.oracle.com/javase/specs/jls/se16/html/jls-15.html#jls-15.28.1
>> [2]
>> https://mail.openjdk.java.net/pipermail/amber-spec-experts/2019-March/001067.html
>>
>> On Sun, Aug 29, 2021 at 9:00 PM Remi Forax<forax at univ-mlv.fr> wrote:
>>> Another case where the spec is weird,
>>> i've converted a project that generate a visitor from a grammar (something like
>>> yacc) to use a switch on type instead.
>>>
>>> Sometimes for a degenerate portion of the grammar i've an empty visitor that
>>> always throw an exception,
>>> the equivalent code with a switch is
>>>
>>> static Object result(Object o) {
>>> return switch (o) {
>>> case Object __ -> throw new AssertionError();
>>> };
>>> }
>>>
>>>
>>> Obviously i can tweak the code generator to generate
>>>
>>> static Object result(Object o) {
>>> throw new AssertionError();
>>> }
>>>
>>> but not be able to compile the former code strike me as odd.
>>>
>>> An expression switch is a poly-expression, so the result type is back-propagated
>>> from the return type of the method result, so it should be Object.
>>>
>>> Moreover, if the switch is not a switch expression but a switch statement, the
>>> code is also valid
>>>
>>> static Object result(Object o) {
>>> switch (o) {
>>> case Object __ -> throw new AssertionError();
>>> }
>>> }
>>>
>>> Not be able to compile a switch expression when there is no explicit result type
>>> but only an implicit type seems arbitrary to me
>>> (this change is backward compatible because it only makes more codes compiling).
>>>
>>> Rémi
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.java.net/pipermail/amber-spec-experts/attachments/20211028/fb8dee94/attachment.htm>
More information about the amber-spec-experts
mailing list