はじめに
この2年ほどTypeScriptでフロントエンド開発ばかりやっております。
以前はJavaを使ったサーバサイド開発も行っていたのですが最後に使ったバージョンはJava 7です。
2017年9月にJava 9がリリースされ、完全に置いていかれている感じになってきたのでJava7からJava9までで
変わった点を一挙にキャッチアップしてみます。
Java 8の主要な新機能
Java8は2014年3月にリリースされました。Java8ではラムダ式やStreamAPIなど、より簡潔にコードをかける機能が追加されました。
Java8の新機能はコードがスマートに書けるようになり、Javaが少し洗練された感じです。
ラムダ式
Javaもやっとラムダ式が使えるようになりました。
// 無名クラスを使用する
Arrays.sort(array, new Comparator<Student>() {
@Override
public int compare(Student s1, Student s2) {
return s1.getAge() - s2.getAge();
}
});
Java8では以下のようにアロー演算子を使って書けるようになりました。
ラムダ式の書き方はいろいろありますが、ここでは省略します。
// ラムダ式を使用できる
Arrays.sort(array, (s1, s2) -> s1.getAge() - s2.getAge());
関数インタフェースを引数にとるメソッドを書くことでユーザがラムダ式を使えるメソッドを定義することもできます。
Stream API
配列などを扱う便利なAPIが追加されました。
Java7まではforなどを使っていた処理がメソッドチェーンで簡潔に記述することができるようになりました。
String[] list = new String[] {
"ABC", "CDE", "EFG"
};
// Java7 for分を使用する
String target = "";
for (String str : list) {
if (str.contains("C")) {
target += str;
}
}
Optional<String> result = Arrays.stream(list).filter(s -> s.contains("C")).reduce((v1, v2) -> v1 + v2);
Optional
Optionalはnullをうまく扱うためのAPIです。nullをラップしてnullかもしれない場合の処理を書けるようになります。
例えばJava7までは以下のようにnullチェックしていたコードが
String str1 = "hoge";
if (str1 != null) {
System.out.println(str1);
}
Optionalを使用すると以下のようにすっきり書けます。
Optional<String> str2 = Optional.ofNullable("hoge");
str2.ifPresent(x -> System.out.println(x));
また以下のようなコードも
String str1 = "hoge";
if (str1 != null) {
System.out.println(str1);
} else {
System.out.println("nullです");
}
以下のようにすっきり書けます。
String str2 = Optional.ofNullable("hoge").orElse("nullです");
System.out.println(str2);
Date and Time API
java8になって新しくjava.timeパッケージが追加され、ISO8601をベースとした日時を扱うさまざまなクラスが追加されました。
最低限覚えておきたいAPIは以下です。
新API | 概要 |
---|---|
LocalDateTime | タイムゾーンのない日時 |
ZonedDateTime | タイムゾーン付きの日時 |
DateTimeFormatter | フォーマッタ。SimpleDateFormatに相当 |
interface
interfaceにデフォルトの実装を持てるようになりました。
以下のようにメソッドとstaticメソッドを書けます。デフォルトメソッドは実装クラスでオーバーライドすることができます。
public interface IDefaultSample {
default void Print(String value) {
System.out.println(value);
}
public static void Hello() {
System.out.println("hello");
}
}
タイプアノテーション
java7まではクラスやメソッドの宣言にしか使用できなかったアノテーションですが、java8から
(変数やジェネリックスの)型にも使用できるようになりました。
Java 9の主要な新機能
次にjava8 から java9の変更点です。一番大きな追加はモジュール化ではないでしょうか。
その他、機能改善が多くあるようです。
モジュール化「Project Jigsaw」
複数のクラスをまとめてモジュールという単位で依存関係・公開設定・バージョン設定等ができるようになりました。
モジュールの定義は「module-info.java」というファイルを記述することで簡単に行えるようです。
こちらのプログラムを参考にしました。
module-info.javaには以下の通りモジュールの宣言と公開するパッケージを宣言します。
ここではorg.astroモジュールの宣言でorg.astroパッケージを公開する設定です。
宣言の説明
- module :モジュールの宣言
- exports :公開するパッケージを指定
module org.astro {
exports org.astro;
}
package org.astro;
public class World {
public static String name() {
return "world";
}
}
次は依存するモジュールを指定する方法です。
com.greetingsモジュールは内部のクラスでorg.astroモジュールを使用しているため
この宣言が必要になります。
宣言の説明
- requires :依存するモジュールを指定
module com.greetings {
requires org.astro;
}
package com.greetings;
import org.astro.World;
public class Main {
public static void main(String[] args) {
System.out.format("Greetings %s!%n", World.name());
}
}
くわしくはこちらに記載されています。
JShell
javaのREPLであるjshellが搭載されました。
REPLとはR(Read)読んでE(Eval)評価してP(Print)出力をL(Loop)繰り返すことです。
ほかの言語では搭載されているものもあります。
使い方はJDKにパスを通すかJDKまで移動し、jshellコマンドを実行します。
これで以下のようにJavaの構文が即時実行できます。
あまり使い道を思いつきませんが、ちょっとしたコードを試すのには良いかもしれません。
interfaceにprivateメソッド
java8で追加された、interfaceにdefaultメソッド、staticメソッドが記述できるようになった機能に追加でprivateメソッドが記述できるようになりました。
Stream API機能追加
java8で追加されたStream APIにtakeWhile、dropWhileメソッドが追加されました。
Reactive Streams
非同期ストリームを実現するためPublish・Subscribeモデルを採用したFrameworkが追加されました。
ITproのこちらの記事に詳しく解説されています。
さいごに
その他たくさんの変更点が含まれていますが、今回は駆け足で主要な変更点について見てきました。