はじめに
2020/3/17にJava 14がリリースされました。
以下の機能が追加されたようです。
下の表の「本記事の対象」列に〇がついているものを少し触ってみたので後で紹介します。
JEP(※1) | 概要 | 本記事の対象 |
---|---|---|
305 | Pattern Matching for instanceof (Preview)(※2) | 〇 |
343 | Packaging Tool (Incubator)(※3) | × |
345 | NUMA-Aware Memory Allocation for G1 | × |
349 | JFR Event Streaming | × |
352 | Non-Volatile Mapped Byte Buffers | × |
358 | Helpful NullPointerExceptions | 〇 |
359 | Records (Preview) | 〇 |
361 | Switch Expressions (Standard) | 〇 |
362 | Deprecate the Solaris and SPARC Ports | × |
363 | Remove the Concurrent Mark Sweep (CMS) Garbage Collector | × |
364 | ZGC on macOS | × |
365 | ZGC on Windows | × |
366 | Deprecate the ParallelScavenge + SerialOld GC Combination | × |
367 | Remove the Pack200 Tools and API | × |
368 | Text Blocks (Second Preview) | 〇 |
370 | Foreign-Memory Access API (Incubator) | × |
公式はこちら
※1 JEP
JDK Enhancement Proposalsの略。
JDKに対する変更の提案を管理する番号。
参考:https://www.slideshare.net/AyaEbata/jsrjepjbs
JEPの目次:https://openjdk.java.net/jeps/0
※2 Preview
プレビュー版のこと。
機能としては保証されているが、どのように使うべきかは議論の余地があるもの。開発者が実際に使ってみて、フィードバックを受けて今後もJava SEの基本機能として提供し続けるかどうかが決まる。
※3 Incubator
開発者からのフィードバックを得るために、Java SEに含めた実験的なAPI。
参考:https://xtech.nikkei.com/it/atcl/column/15/120700278/080700044/
Java 14をEclipseで使えるようにするための設定
私はEclipse使いなので、JDK 14のインストールとEclipseの設定から始めます。
JDKダウンロード
以下のサイトからJDK14をダウンロードします。
https://www.oracle.com/java/technologies/javase-downloads.html
Eclipseインストール
Eclipseの最新版をインストールします。
https://www.eclipse.org/eclipseide/
EclipseでJDK14を扱えるようにする
EclipseでJDK14を扱えるようにする手順は以下の通り。
②Java 14 Support for Eclipse をインストール
※こういったEclipse本体やプラグインのリリース情報は公式のtwitterからも流れてくるので興味ある方はフォローすることをお勧めします。
🌟 Here is the new me! Eclipse IDE 2020-03! 🌟
— 🌒 Eclipse Java IDE (@EclipseJavaIDE) March 18, 2020
Many improvements for users to leverage in many places
📰 https://t.co/tEp3O53CvA and https://t.co/lQsBQecjUb !
☕ Support for JDK 14 is also released today, at https://t.co/bqDu2awnjL
🙏 Thanks to my contributors!
③Compiler compliance levelを14に設定
※Java 14 Support for Eclipse をインストールしないと14が選択肢に出ません。
④Installed JREに、インストールしたJDK14を設定
⑤Execution emvironmentにJDK14を設定
⑥今回はプレビューの機能も使うので、プレビューを有効化します。
これでJava 14を使ったJavaアプリケーションをEclipseで開発・実行できるようになります。
Java 14の新機能を触ってみる
早速触ってみました。
JEP 305:Pattern Matching for instanceof (Preview)
まずはJEP 305のPattern Matching for instanceofです。
instanceof と同時に変数を定義できるようになりました。
実際の書き方の例は以下の通りです。
前半がこれまでの書き方、後半がPattern Matching for instanceofを使用した書き方になっています。
まずはこれまでの書き方。
public class NotPatternMatchingTest {
public static void main(String... args) {
patternMatch("literal");
patternMatch(1);
}
private static void patternMatch(Object obj) {
// これまでの書き方
if (obj instanceof String) {
String str = (String) obj;
System.out.println("No Pattern Matching:" + str);
} else if (obj instanceof Integer) {
Integer inte = (Integer) obj;
System.out.println("No Pattern Matching:" + inte);
}
}
}
これがPattern Matching for instanceof を使用した書き方。
public class PatternMatchingTest {
public static void main(String... args) {
patternMatch("literal");
patternMatch(1);
}
// previewなのでSuppressWarningsでワーニング抑止
@SuppressWarnings("preview")
private static void patternMatch(Object obj) {
// Pattern Matching for instanceof
if (obj instanceof String str) {
System.out.println("Pattern Matching:" + str);
} else if (obj instanceof Integer inte) {
System.out.println("Pattern Matching:" + inte);
}
}
}
switch文での使用はJava 15以降に持ち越しになっているようです。
http://openjdk.java.net/jeps/8213076
JEP 358:Helpful NullPointerExceptions
NullPointerExceptionが発生した場合のメッセージが詳細になり、原因を特定しやすくなりました。
-XX:+ShowCodeDetailsInExceptionMessages
オプションをつけて実行することで、詳細なメッセージを得ることができます。
以下のサンプルコードで実験してみました。
public class HelpfulNullPo {
public static void main(String... args) {
String str = null;
str.length();
}
}
-XX:+ShowCodeDetailsInExceptionMessages
オプションを付けずに実行した結果がこちら。
Exception in thread "main" java.lang.NullPointerException
at test.HelpfulNullPo.main(HelpfulNullPo.java:6)
-XX:+ShowCodeDetailsInExceptionMessages
オプションをつけて実行した結果がこちら。
Exception in thread "main" java.lang.NullPointerException: Cannot invoke "String.length()" because "str" is null
at test.HelpfulNullPo.main(HelpfulNullPo.java:6)
NullPointerExceptionの原因特定がしやすくなっています。
なお、JShellの場合は-R-XX:+ShowCodeDetailsInExceptionMessages
という指定になります。
JEP 359:Records (Preview)
データ保持用のクラスとしてrecordという機能がpreviewとして入りました。
以下のように書くだけでデータ保持用のクラスを作ることができます。
(record Person(String name, int age) {}
の部分)
@SuppressWarnings("preview")
record Person(String name, int age) {}
public class RecordTest {
public static void main(String... args) {
Person person = new Person("taumax", 13);
System.out.println("name:" + person.name());
System.out.println("age:" + person.age());
System.out.println(person);
}
}
name:taumax
age:13
Person[name=taumax, age=13]
インスタンス生成後に値を変更することはできないようです。
厳密には違いますが、イメージ的にはイミュータブルなJavaBeansを簡単に作ることができるようになったという感覚ですかね。
JEP 361:Switch Expressions (Standard)
Switch文がアロー->
を使って書けるようになり、かなり読みやすくなりました。また、breakの記載も不要になっています。
Switch ExpressionsはJava 12でプレビューとして導入されたものですが、今回のJava 14で正式機能として導入されます。
実際の書き方の例は以下の通りです。
前半がこれまでの書き方、後半がSwitch Expressionsを使用した書き方になっています。
まずはこれまでのswitch文
public class OldSwitchExpressions {
public static void main(String... args) {
for (Week day : Week.values()) {
oldSwitch1(day);
}
}
// これまでのswitch文
private static void oldSwitch1(Week day) {
System.out.print("old:");
switch (day) {
case MONDAY, FRIDAY, SUNDAY:
System.out.println(6);
break;
case TUESDAY:
System.out.println(7);
break;
case THURSDAY, SATURDAY:
System.out.println(8);
break;
case WEDNESDAY:
System.out.println(9);
break;
}
}
private enum Week {
SUNDAY, MONDAY, TUESDAY, WEDNESDAY,
THURSDAY, FRIDAY, SATURDAY
}
}
これがSwitch Expressions
public class SwitchExpressions {
public static void main(String... args) {
for (Week day : Week.values()) {
newSwitch1(day);
}
}
// 新しいswitch文
private static void newSwitch1(Week day) {
System.out.print("new:");
switch (day) {
case MONDAY, FRIDAY, SUNDAY -> System.out.println(6);
case TUESDAY -> System.out.println(7);
case THURSDAY, SATURDAY -> System.out.println(8);
case WEDNESDAY -> System.out.println(9);
}
}
private enum Week {
SUNDAY, MONDAY, TUESDAY, WEDNESDAY,
THURSDAY, FRIDAY, SATURDAY
}
}
アロー->
を使い、breakがなくなったことでかなり可読性が高くなったことがわかります。
また、switch文の実行結果をそのまま変数に代入することができるようになりました。
実際の書き方の例は以下の通りです。
前半がこれまでの書き方、後半がSwitch Expressionsを使用した書き方になっています。
まずはこれまでの書き方。
public class OldSwitchExpressions2 {
public static void main(String... args) {
for (Week day : Week.values()) {
oldSwitch2(day);
}
}
// これまでのswitch文
private static void oldSwitch2(Week day) {
System.out.print("old:");
int numLetters;
switch (day) {
case MONDAY, FRIDAY, SUNDAY:
numLetters = 6;
break;
case TUESDAY:
numLetters = 7;
break;
case THURSDAY, SATURDAY:
numLetters = 8;
break;
case WEDNESDAY:
numLetters = 9;
break;
default:
throw new IllegalStateException("Wat: " + day);
}
System.out.println(numLetters);
}
private enum Week {
SUNDAY, MONDAY, TUESDAY, WEDNESDAY,
THURSDAY, FRIDAY, SATURDAY
}
}
続いてSwitch Expressionsを使用した書き方。
public class SwitchExpressions2 {
public static void main(String... args) {
for (Week day : Week.values()) {
newSwitch2(day);
}
}
// 新しいswitch文
private static void newSwitch2(Week day) {
System.out.print("new:");
int numLetters = switch (day) {
case MONDAY, FRIDAY, SUNDAY -> 6;
case TUESDAY -> 7;
case THURSDAY, SATURDAY -> 8;
case WEDNESDAY -> 9;
};
System.out.println(numLetters);
}
private enum Week {
SUNDAY, MONDAY, TUESDAY, WEDNESDAY,
THURSDAY, FRIDAY, SATURDAY
}
}
これの効果は一目瞭然ですね。素晴らしい!
JEP 368:Text Blocks (Second Preview)
改行などを含んだ文字列を定義できるようになりました。
文字列を定義する場合の"
ではなく"""
で囲みます。
開始の"""
のあとには文字列を続けることができません。
public class TextBlocks {
@SuppressWarnings("preview")
public static void main(String... args) {
// これまでは改行をエスケープする必要があった。
String str1 = "I have a pen.\n"
+ "I don't have a pen.";
System.out.println(str1);
// エスケープしなくても改行してくれる。
String str2 = """
I have a pen.
I don't have a pen.
""";
System.out.println(str2);
// 改行したくない場合は「\」を付ける。
String str3 = """
I have a pen.\
I don't have a pen.\
""";
System.out.println(str3);
// 文字列に変数を埋め込む場合
String str4 = """
Hello %s.
""".formatted("taumax");
System.out.println(str4);
}
}
I have a pen.
I don't have a pen.
I have a pen.
I don't have a pen.
I have a pen.I don't have a pen.
Hello taumax.
以上。
参考
・Oracle、「Java 14」を発表 ~Recordクラスがプレビュー導入、switch式が正式機能に
・Java 14がリリース