Enum: difference of behaviour between exhaustive switch vs. using default:

Remi Forax forax at univ-mlv.fr
Wed Dec 11 12:44:38 UTC 2024


Hello, 
I think it can be reduced to 
public enum Action { IGNORE , REJECT } 
private static void bad () { 
String s ; 
switch ( getAction ()) { 
case IGNORE : 
s = "foo" ; 
break ; 
case REJECT : 
throw new RuntimeException( "REJECTED" ); 
}; 
System . out .println( s ); // <------- variable s might not have been initialized 
} 

private static void ok () { 
String s = switch ( getAction ()) { 
case IGNORE : 
yield "foo" ; 
case REJECT : 
throw new RuntimeException( "REJECTED" ); 
}; 
System . out .println( s ); // ok ! 
} 

so there is a bug in DA/DU rules and the workaround is to use a switch expression. 

Rémi 

> From: "Gavin Bierman" <gavin.bierman at oracle.com>
> To: "Jean-Noël Rouvignac (ForgeRock)" <jean-noel.rouvignac at pingidentity.com>
> Cc: "amber-dev" <amber-dev at openjdk.org>
> Sent: Wednesday, December 11, 2024 1:20:15 PM
> Subject: Re: Enum: difference of behaviour between exhaustive switch vs. using
> default:

> Could you file this as a bug, and I will take a look?

> Thanks,
> Gavin

>> On 10 Dec 2024, at 16:10, Jean-Noël Rouvignac (ForgeRock)
>> <jean-noel.rouvignac at pingidentity.com> wrote:

>> Hello amber-dev experts!

>> I am modernizing our codebase by making it use enhanced / exhaustive switches.

>> In several places, I replaced `default: ` by `case THE_ONLY_UNUSED_ENUM_VALUE:`,
>> except that I am hitting an unexpected difference in behaviour, at least from
>> my point of view.

>> I have reduced the code to the following reproducer (tested on the [
>> https://dev.java/playground/ |
>> https://dev.java/playground/ ] ), where `main1()` compiles, but `main2()` does
>> not. And yet, I am under the impression both should be equivalent?


>> What do you think?
>> Thanks a lot.

>> import java.io.IOException;

>> class Main {
>> public enum Action { IGNORE, REJECT }

>> public static void main(String[] args) {
>> main1();
>> main2();
>> }

>> private static void main1() {
>> String s;
>> try {
>> s = getValue();
>> } catch (IOException e) {
>> switch (getAction()) {
>> case IGNORE:
>> return;
>> default:
>> throw new RuntimeException("REJECTED");
>> }
>> }

>> System.out.println(s);
>> }

>> private static void main2() {
>> String s;
>> try {
>> s = getValue();
>> } catch (IOException e) {
>> switch (getAction()) {
>> case IGNORE:
>> return;
>> case REJECT: // <------------------- Fails compilation
>> throw new RuntimeException("REJECTED");
>> }
>> }

>> System.out.println(s); // <------- Main.java:40: error: variable s might not
>> have been initialized
>> }

>> static Action getAction() {
>> return Action.IGNORE;
>> }

>> static String getValue() throws IOException {
>> return "SUCCESS";
>> }
>> }




>> CONFIDENTIALITY NOTICE: This email may contain confidential and privileged
>> material for the sole use of the intended recipient(s). Any review, use,
>> distribution or disclosure by others is strictly prohibited. If you have
>> received this communication in error, please notify the sender immediately by
>> e-mail and delete the message and any file attachments from your computer.
>> Thank you.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/amber-dev/attachments/20241211/b32ed225/attachment.htm>


More information about the amber-dev mailing list