Java12 came out, so I tried the switch expression for the time being

Overview

Java 12 is out. I think there are various changes and new functions, but I tried the switch statement (or switch expression), which is the most obvious change.

important point

The way to write a new switch statement seems to be positioned as a preview function as of Java 12, and you have to add options at compile time and execution time.

At compile time

javac --enable-preview --release 12  MultiCaseSample.java

runtime

java --enable-preview MultiCaseSample

Also, the content written here is subject to change in the future.

Contents

Multiple cases

You can specify multiple values in the case clause, separated by commas.

public class MultiCaseSample {
    public static void main(String[] args) {
        var month = Integer.parseInt(args[0]);

        switch(month) {
            case 1, 2:
                System.out.println("It's winter");
                break;
            case 3, 4, 5:
                System.out.println("It's spring");
                break;
            case 6, 7, 8:
                System.out.println("Summer is in full swing");
                break;
            case 9, 10, 11:
                System.out.println("Our autumn is just around the corner!");
                break;
            case 12:
                System.out.println("It's the end of the year, so I'll start next year");
                break;
            default:
                System.out.println("There is no such month");
        }
    }
}

Arrow syntax

Write a sentence after the "->" symbol. You can omit the description of colon and break. It seems that you can write multi-line processing by using blocks. (In the example below, it's one line ...) Also, you don't need a semicolon after the block closing parenthesis.

public class ArrowSample {
    public static void main(String[] args) {
        var month = Integer.parseInt(args[0]);

        switch(month) {
            case 1, 2 -> System.out.println("It's winter");
            case 3, 4, 5 -> System.out.println("It's spring");
            case 6, 7, 8 -> System.out.println("Summer is in full swing");
            case 9, 10, 11 -> System.out.println("Our autumn is just around the corner!");
            case 12 -> System.out.println("It's the end of the year, so I'll start next year");
            default -> {
                System.out.println("There is no such month");
            }
        }
    }
}

switch type

The switch statement is now a switch expression. The difference between a statement and an expression is that the former does not return a value, while the latter returns a value. So, you can assign the evaluation result of the switch expression to the variable as it is. In this case, a semicolon is required after the closing parenthesis of the switch.

Also, if all patterns are not covered (in this example, there is no default clause), a compile error will occur. It's better than implicitly assigning null. If you don't use the arrow syntax or use blocks, the value to be returned is described after break.

public class SwitchExpressionSample {
    public static void main(String[] args) {
        var month = Integer.parseInt(args[0]);

        var message = switch(month) {
            case 1, 2 -> "It's winter";
            case 3, 4, 5 -> "It's spring";
            case 6, 7, 8 -> {
                break "Summer is in full swing";
            }
            case 9, 10, 11 -> "Our autumn is just around the corner!";
            case 12 -> "It's the end of the year, so I'll start next year";
            default -> "There is no such month";
        };
        System.out.println(message);
    }
}

Apparently, mixing the arrow syntax with the traditional syntax results in a compile error. So I wrote a pattern that doesn't use arrow syntax.

public class SwitchExpressionBreakSample {
    public static void main(String[] args) {
        var month = Integer.parseInt(args[0]);

        var message = switch(month) {
            case 1, 2:
                break "It's winter";
            case 3, 4, 5:
                break "It's spring";
            case 6, 7, 8:
                break "Summer is in full swing";
            case 9, 10, 11:
                break "Our autumn is just around the corner!";
            case 12:
                break "It's the end of the year, so I'll start next year";
            default:
                break "There is no such month";
        };
        System.out.println(message);
    }
}

Other things I was interested in

Is default unnecessary when enumerating all elements with Enum?

Even without default, it worked without any errors at compile time and run time.

public class SwitchExpressionEnumSample {

    private enum Month {
        JANUARY, FEBRUARY, MARCH, APRIL, MAY, JUNE,
        JULY, AUGUST, SEPTEMBER, OCTOBER, NOVEMBER, DECEMBER,
    }

    public static void main(String[] args) {
        var month = Month.values()[Integer.parseInt(args[0])];

        var message = switch(month) {
            case JANUARY, FEBRUARY -> "It's winter";
            case MARCH, APRIL, MAY -> "It's spring";
            case JUNE, JULY, AUGUST -> "Summer is in full swing";
            case SEPTEMBER, OCTOBER, NOVEMBER -> "Our autumn is just around the corner!";
            case DECEMBER -> "It's the end of the year, so I'll start next year";
        };
        System.out.println(message);
    }
}

What happens if the switch condition is null in the first place?

It is a pattern that has been possible for a long time regardless of this release, but in the above Enum example, there is no case for null, and I was wondering if it can be said that it is covered.

public class SwitchExpressionNullSample {

    private enum Month {
        JANUARY, FEBRUARY, MARCH, APRIL, MAY, JUNE,
        JULY, AUGUST, SEPTEMBER, OCTOBER, NOVEMBER, DECEMBER,
    }

    public static void main(String[] args) {
        Month month = null;

        var message = switch(month) {
            case JANUARY, FEBRUARY -> "It's winter";
            case MARCH, APRIL, MAY -> "It's spring";
            case JUNE, JULY, AUGUST -> "Summer is in full swing";
            case SEPTEMBER, OCTOBER, NOVEMBER -> "Our autumn is just around the corner!";
            case DECEMBER -> "It's the end of the year, so I'll start next year";
        };
        System.out.println(message);
    }
}

The result was as follows. (Nullpo in the switch (month) part) Well, that's right.

Exception in thread "main" java.lang.NullPointerException
        at SwitchExpressionNullSample.main(SwitchExpressionNullSample.java:11)

(Added on May 21, 2019) Will an error occur if Enum does not cover all the elements?

The essential pattern was leaking ... Comment it out and see what happens.

public class SwitchExpressionEnumSample {

    private enum Month {
        JANUARY, FEBRUARY, MARCH, APRIL, MAY, JUNE,
        JULY, AUGUST, SEPTEMBER, OCTOBER, NOVEMBER, DECEMBER,
    }

    public static void main(String[] args) {
        var month = Month.values()[Integer.parseInt(args[0])];

        var message = switch(month) {
            case JANUARY, FEBRUARY -> "It's winter";
            case MARCH, APRIL, MAY -> "It's spring";
            case JUNE, JULY, AUGUST -> "Summer is in full swing";
            case SEPTEMBER, OCTOBER, NOVEMBER -> "Our autumn is just around the corner!";
        //    case DECEMBER -> "It's the end of the year, so I'll start next year";
        };
        System.out.println(message);
    }
}

The results are as follows. After all it seems that a compile error occurs. It helps prevent bugs caused by leaks. It doesn't seem to tell you exactly which element is leaking.

 SwitchExpressionEnumSample.java:11: Error: switch expression does not cover all possible input values
        var message = switch(month) {
                      ^

(Added on September 26, 2019) Changes in Java 13

Java 13 has been released, but Switch-style features are still in preview. However, there are some changes in the grammar, so I will add it.

If you don't use arrow syntax or use blocks, the value to be returned is described after break.

Changed in Java 13 to use yield instead of break.

public class SwitchExpressionSample {
    public static void main(String[] args) {
        var month = Integer.parseInt(args[0]);

        var message = switch(month) {
            case 1, 2 -> "It's winter";
            case 3, 4, 5 -> "It's spring";
            case 6, 7, 8 -> {
                yield "Summer is in full swing";
                //↑ This
            }
            case 9, 10, 11 -> "Our autumn is just around the corner!";
            case 12 -> "It's the end of the year, so I'll start next year";
            default -> "There is no such month";
        };
        System.out.println(message);
    }
}

(Added on 2020/3/18) Java 14 released

With the release of Java14, switch statements have become a formal feature. It seems that the specifications will not change from Java 13.

Impressions

I thought it was convenient. (Konami) You can prevent bugs due to break omissions by using the arrow syntax, and you can prevent bugs due to value pattern omissions by substituting the result of the switch expression as it is. Also, in the past, there was a technique to make it fall through without writing break, and if you use the arrow syntax, you can not do it, but I think that it will not be a problem because you can specify multiple cases.

Reference link

Recommended Posts

Java12 came out, so I tried the switch expression for the time being
Java14 came out, so I tried record for the time being
I tried using Docker for the first time
I tried touching Docker for the first time
Use Java external library for the time being
Run Dataflow, Java, streaming for the time being
The training for newcomers was "Make an app!", So I made an app for the time being.
I want you to use Scala as Better Java for the time being
[Rails] I tried using the button_to method for the first time
I tried the Java framework "Quarkus"
Introduction to java for the first time # 2
I tried Cassandra's Object Mapper for Java
Java9 was included, so I tried jshell.
I tried the new era in Java
Learning for the first time java [Introduction]
For the time being, run the war file delivered in Java with Docker
Glassfish tuning list that I want to keep for the time being
[First Java] Make something that works with Intellij for the time being
Install Amazon Corretto (preview) for the time being
Since the docker-desktop preview for m1 came out, I tried to face it with my macbook pro 15inch
[Deep Learning from scratch] in Java 1. For the time being, differentiation and partial differentiation
I tried using the Migration Toolkit for Application Binaries
Learn for the first time java # 3 expressions and operators
Try running Spring Cloud Config for the time being
I tried using an extended for statement in Java
Learning memo when learning Java for the first time (personal learning memo)
I tried to implement the Euclidean algorithm in Java
Command to try using Docker for the time being
I tried to find out what changed in Java 9
I finished watching The Rose of Versailles, so I tried to reproduce the ending song in Java
Access Web API on Android with Get and process Json (Java for the time being)
I translated [Clone method for Java arrays] as the Clone method in Java arrays.
[JDBC] I tried to access the SQLite3 database from Java.
I tried to summarize the basics of kotlin and java
Hello World with Ruby extension library for the time being
Java SE 13 (JSR388) has been released so I tried it
Java review ③ (control syntax [if / switch / while / for], conditional expression)
I tried using the CameraX library with Android Java Fragment
[Memo] Run Node.js v4.4.5 on CentOS 4.9 / RHEL4 (i386) for the time being (gcc-4.8 and glibc2.11 on LinuxKernel 2.6.9)
I tried Drools (Java, InputStream)
I tried the Docker tutorial!
I tried the VueJS tutorial!
I tried using Java REPL
I tried the FizzBuzz problem
[Java] I implemented the combination.
I studied the constructor (java)
I tried metaprogramming in Java
I passed the Java test level 2 so I will leave a note
I tried the input / output type of Java Lambda ~ Map edition ~
I tried to translate the error message when executing Eclipse (Java)
I tried to summarize the methods of Java String and StringBuilder
[Java] I tried to make a maze by the digging method ♪
I tried to move the Java compatible FaaS form "Fn Project"
I passed the Oracle Java Bronze, so I summarized the outline of the exam.
I tried to display the calendar on the Eclipse console using Java.