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.
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.
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");
}
}
}
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");
}
}
}
}
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);
}
}
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);
}
}
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)
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) { ^
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);
}
}
With the release of Java14, switch statements have become a formal feature. It seems that the specifications will not change from Java 13.
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.
Recommended Posts