例を使って Java 9 の機能を学ぶ

Java 9は重要なリリースであり、開発者に多くの機能をもたらしました。この記事では、Java 9の機能について詳しく見ていきます。

Java 10もリリースされました。Java 10のリリースの完全な概要については、Java 10の機能をご覧ください。

Java 9の機能

いくつかの重要なJava 9の機能は、

  1. Java 9 REPL(JShell)
  2. Immutable List、Set、Map、およびMap.Entryのファクトリメソッド
  3. インターフェースでのプライベートメソッド
  4. Java 9モジュールシステム
  5. プロセスAPIの改善
  6. リソースの試行と終了の改善
  7. CompletableFuture APIの改善
  8. リアクティブストリーム
  9. 匿名内部クラスのためのダイヤモンド演算子
  10. Optionalクラスの改善
  11. Stream APIの改善
  12. 強化された@Deprecatedアノテーション
  13. HTTP 2クライアント
  14. マルチ解像度画像API
  15. その他のJava 9機能

オラクル株式会社は2017年3月末頃にJava SE 9をリリースする予定です。この記事では、いくつかの例を交えて「Java 9の機能」について簡単に説明します。

Java 9 REPL(JShell)

オラクル社は、「jshell」と呼ばれる新しいツールを導入しました。これはJavaシェルとしても知られており、REPL(Read Evaluate Print Loop)としても知られています。これは、クラス、インターフェース、列挙型、オブジェクト、ステートメントなどのJava構造を非常に簡単に実行およびテストするために使用されます。JDK 9 EA(アーリーアクセス)ソフトウェアは、https://jdk9.java.net/download/からダウンロードできます。

G:\>jshell
|  Welcome to JShell -- Version 9-ea
|  For an introduction type: /help intro


jshell> int a = 10
a ==> 10

jshell> System.out.println("a value = " + a )
a value = 10

REPLツールについて詳しく知りたい場合は、Java 9 REPL Basics(Part-1)Java 9 REPL Features(Part-2)をご覧ください。

不変リスト、セット、マップ、およびMap.Entryのためのファクトリメソッド

Oracle Corpは、Immutable List、Set、Map、およびMap.Entryオブジェクトを作成するための便利なファクトリメソッドをいくつか導入しました。これらのユーティリティメソッドは、空のまたは空でないコレクションオブジェクトを作成するために使用されます。Java SE 8およびそれ以前のバージョンでは、Immutable Collectionオブジェクトを作成するためにunmodifiableXXXのようなCollectionsクラスのユーティリティメソッドを使用できます。たとえば、Immutable Listを作成したい場合は、Collections.unmodifiableListメソッドを使用できます。ただし、これらのCollections.unmodifiableXXXメソッドは手間がかかり、冗長なアプローチです。これらの欠点を克服するために、Oracle CorpはList、Set、およびMapインターフェースにいくつかのユーティリティメソッドを追加しました。ListおよびSetインターフェースには、以下に示すように、空のまたは空でないImmutable ListまたはSetオブジェクトを作成するための「of()」メソッドがあります:空のリストの例

List immutableList = List.of();

空でないリストの例

List immutableList = List.of("one","two","three");

マップには、Immutable MapオブジェクトおよびImmutable Map.Entryオブジェクトを作成するためのof()メソッドおよびofEntries()メソッドの2つのセットがあります。空のマップの例

jshell> Map emptyImmutableMap = Map.of()
emptyImmutableMap ==> {}

空でないマップの例

jshell> Map nonemptyImmutableMap = Map.of(1, "one", 2, "two", 3, "three")
nonemptyImmutableMap ==> {2=two, 3=three, 1=one}

これらのユーティリティメソッドについて詳しく読みたい場合は、次のリンクを参照してください:

インタフェース内のプライベートメソッド

Java 8では、デフォルトメソッドと静的メソッドを使用してインタフェース内でメソッドの実装を提供できます。ただし、インタフェース内でプライベートメソッドを作成することはできません。冗長なコードを避け、さらなる再利用性を確保するために、Oracle CorpはJava SE 9インタフェースでプライベートメソッドを導入する予定です。Java SE 9以降、’private’キーワードを使用してインタフェース内にプライベートおよびプライベート静的メソッドを記述できます。これらのプライベートメソッドは、他のクラスのプライベートメソッドと同じように、他とは違いはありません。

public interface Card{

  private Long createCardID(){
    // メソッドの実装はここに記述します。
  }

  private static void displayCardDetails(){
    // メソッドの実装はここに記述します。
  }

}

この新機能について詳しく読みたい場合は、このリンクをご覧ください:Java 9インタフェース内のプライベートメソッド

Java 9モジュールシステム

Java 9の大きな変更点または機能の1つは、モジュールシステムです。Oracle Corpは、以下の機能をJigsawプロジェクトの一部として導入する予定です。

  • モジュラーJDK
  • モジュラーJavaソースコード
  • モジュラーランタイムイメージ
  • Java内部APIをカプセル化
  • Javaプラットフォームモジュールシステム

Java SE 9以前のバージョンでは、Javaベースのアプリケーションを開発するためにモノリシックJARを使用していました。このアーキテクチャには多くの制限と欠点があります。これらすべての欠点を回避するために、Java SE 9はモジュールシステムを導入しています。JDK 9には92のモジュールが含まれています(最終リリース時に変更される可能性があります)。JDKモジュールを使用することも、次に示すように独自のモジュールを作成することもできます:シンプルなモジュールの例

module com.foo.bar { }

ここでは、単純なモジュールを作成するために ‘module’ を使用しています。各モジュールには名前、関連するコード、およびその他のリソースがあります。この新しいアーキテクチャの詳細や実践的な経験については、こちらの私のオリジナルのチュートリアルを参照してください:

プロセスAPIの改善

Java SE 9には、プロセスAPIの改善がいくつかあります。OSプロセスの制御と管理を容易にするために、いくつかの新しいクラスとメソッドが追加されました。プロセスAPIの2つの新しいインターフェース:

プロセスAPIの例

 ProcessHandle currentProcess = ProcessHandle.current();
 System.out.println("Current Process Id: = " + currentProcess.getPid());

Try With Resourcesの改善

私たちは、Java SE 7がリソースを自動的に管理するための新しい例外処理構文:Try-With-Resourcesを導入したことを知っています。この新しい文の主な目標は「自動的により良いリソース管理」です。 Java SE 9では、この文のいくつかの改善が行われ、さらなる冗長性の回避と読みやすさの向上が図られます。Java SE 7の例

void testARM_Before_Java9() throws IOException{
 BufferedReader reader1 = new BufferedReader(new FileReader("journaldev.txt"));
 try (BufferedReader reader2 = reader1) {
   System.out.println(reader2.readLine());
 }
}

Java 9の例

void testARM_Java9() throws IOException{
 BufferedReader reader1 = new BufferedReader(new FileReader("journaldev.txt"));
 try (reader1) {
   System.out.println(reader1.readLine());
 }
}

この新機能について詳しく読みたい場合は、オリジナルのチュートリアルを参照してください:Java 9 Try-With-Resources の改善

CompletableFuture API の改善

Java SE 9 では、Oracle Corp が CompletableFuture API を改善し、Java SE 8 で発生したいくつかの問題を解決する予定です。遅延とタイムアウトのサポートを追加し、ユーティリティメソッドとより良いサブクラス化をサポートする予定です。

Executor exe = CompletableFuture.delayedExecutor(50L, TimeUnit.SECONDS);

ここでの delayedExecutor() は、指定された遅延の後にタスクをデフォルトのエグゼキューターに提出する新しいエグゼキューターを返すために使用される静的ユーティリティメソッドです。

リアクティブストリーム

近年、リアクティブプログラミングは、いくつかの素晴らしい利点を得るためにアプリケーションの開発で非常に人気があります。Scala、Play、Akka などのフレームワークはすでにリアクティブストリームを統合し、多くの利点を得ています。Oracle Corps も Java SE 9 で新しいリアクティブストリーム API を導入しています。Java SE 9 のリアクティブストリーム API は、Java 言語を使用して非同期、スケーラブル、並列アプリケーションを非常に簡単に実装するための Publish/Subscribe フレームワークです。Java SE 9 は、Java ベースのアプリケーションでリアクティブストリームを開発するための以下の API を導入しました。

  • java.util.concurrent.Flow
  • java.util.concurrent.Flow.Publisher
  • java.util.concurrent.Flow.Subscriber
  • java.util.concurrent.Flow.Processor

は、Java 9 Reactive Streamsで詳細を確認してください。

匿名内部クラスのためのダイヤモンド演算子

Java SE 7では、冗長なコードと冗長性を避け、可読性を向上させるために、新しい機能であるダイヤモンド演算子が導入されました。しかし、Java SE 8では、Oracle Corp(Javaライブラリ開発者)がダイヤモンド演算子を匿名内部クラスと使用する際のいくつかの制限を見つけました。これらの問題を修正し、Java 9の一環としてリリースする予定です。

  public List getEmployee(String empid){
     // データストアから従業員の詳細を取得するためのコード
     return new List(emp){ };
  }

ここでは、タイプパラメータを指定せずに単に「List」を使用しています。

Optionalクラスの改善

Stream<Optional> emp = getEmployee(id)
Stream empStream = emp.flatMap(Optional::stream)

Java SE 9で、Oracle Corpはjava.util.Optionalクラスにいくつかの有用な新しいメソッドを追加しました。ここではその中の一つ、streamメソッドについて簡単な例を交えて説明します。このstream()メソッドは、与えられたOptionalオブジェクト内で値が存在する場合、その値を持つ順次のStreamを返します。それ以外の場合は、空のStreamを返します。彼らはこの”stream()”メソッドをOptionalオブジェクトで遅延的に処理するために追加しました。下記のようにOptional.stream()メソッドを使用して、EmployeeオブジェクトのOptionalのStreamをEmployeeのStreamに変換し、その結果に対して遅延的に作業できます。この機能についてさらに理解し、Optionalクラスに追加された他の新しいメソッドを詳しく知りたい場合は、以下の私の元のチュートリアルを参照してください:Java SE 9: Optionalクラスの改良

Stream APIの改良

Java SE 9で、Oracle Corpはjava.util.Streamインターフェースに4つの便利な新しいメソッドを追加しました。Streamはインターフェースなので、これらの新しい実装メソッドはデフォルトメソッドです。そのうちの2つは非常に重要です:dropWhileメソッドとtakeWhileメソッドです。Scala言語やその他の関数型プログラミング言語に詳しい場合、これらのメソッドについて既に知っているかもしれません。これらは、いくつかの関数スタイルのコードを書く際に非常に便利なメソッドです。ここでは、takeWhileユーティリティメソッドについて説明します。takeWhile()は、述語を引数として受け取り、その述語が最初にfalseを返すまでの部分ストリームを返します。最初の値がその述語を満たさない場合、空のストリームを返します。

jshell> Stream.of(1,2,3,4,5,6,7,8,9,10).takeWhile(i -> i < 5 )
                 .forEach(System.out::println);
1
2
3
4

takeWhileメソッドやdropWhileメソッド、その他の新しいメソッドについて詳しくは、以下のオリジナルのチュートリアルを参照してください:Java SE 9: Stream APIの改善

強化された@Deprecatedアノテーション

Java SE 8 以前では、@Deprecated アノテーションは、メソッドを持たないマーカーインターフェースに過ぎませんでした。これは、クラス、フィールド、メソッド、インターフェース、コンストラクター、列挙型など、Java API をマークするために使用されます。Java SE 9 では、Oracle Corp は @Deprecated アノテーションを拡張し、非推奨の API に関するより多くの情報を提供し、また、アプリケーションの静的な非推奨 API の使用状況を分析するための Tool も提供しています。この Deprecated インターフェースには、この情報を提供するための forRemovalsince という2つのメソッドが追加されています。

HTTP 2 クライアント

Java SE 9では、Oracle CorpがHTTP/2プロトコルとWebSocket機能をサポートするために新しいHTTP 2 Client APIをリリースする予定です。既存のまたはレガシーのHTTP Client APIには多くの問題があります(HTTP/1.1プロトコルをサポートしており、HTTP/2プロトコルとWebSocketをサポートしていない、ブロッキングモードでのみ動作し、多くのパフォーマンスの問題があるなど)。そのため、このHttpURLConnection APIを新しいHTTPクライアントで置き換える予定です。彼らは「java.net.http」パッケージの下に新しいHTTP 2 Client APIを導入する予定です。これは、HTTP/1.1およびHTTP/2プロトコルの両方をサポートしています。同期(ブロッキングモード)および非同期モードの両方をサポートしています。 WebSocket APIを使用した非同期モードもサポートしています。この新しいAPIは、以下で確認できます:https://download.java.net/java/jdk9/docs/api/java/net/http/package-summary.htmlHTTP 2 Client Example

jshell> import java.net.http.*

jshell> import static java.net.http.HttpRequest.*

jshell> import static java.net.http.HttpResponse.*

jshell> URI uri = new URI("https://rams4java.blogspot.co.uk/2016/05/java-news.html")
uri ==> https://rams4java.blogspot.co.uk/2016/05/java-news.html

jshell> HttpResponse response = HttpRequest.create(uri).body(noBody()).GET().response()
response ==> java.net.http.HttpResponseImpl@79efed2d

jshell> System.out.println("Response was " + response.body(asString()))

私の元のチュートリアルを確認してください:Java SE 9: HTTP 2 Client HTTP/2プロトコルとWebSocket、新しいAPIの利点、および古いAPIの欠点を理解するための役立つ例が含まれています。

Multi-Resolution Image API

Java SE 9では、Oracle Corpが新しいMulti-Resolution Image APIを導入する予定です。このAPIの重要なインターフェイスはMultiResolutionImageです。これは、java.awt.imageパッケージで利用できます。 MultiResolutionImageは、異なる高さと幅(異なる解像度)を持つ画像セットをカプセル化し、要件に応じてそれらをクエリできるようにします。

Java 9の機能の中で、その他のもの

このセクションでは、いくつかのJava SE 9の新機能をリストアップします。これらは重要な機能ではありませんが、重要であり、いくつかの有用な例を理解するのに役立ちます。現時点では、これらの機能に関する十分な情報を得ていません。これらの機能を簡単に理解するために、ここにリストアップします。これらの機能を1つずつ選んで、上記のセクションに追加し、簡単な議論と例を追加します。そして、後で別のチュートリアルを書きます。

  • GC(Garbage Collector)の改善
  • スタックウォーキングAPI
  • フィルタリングされたシリアル化データの受信
  • Applet APIの非推奨化
  • 文字列の連結のインディファイ
  • 強化されたメソッドハンドル
  • Javaプラットフォームのログ記録APIとサービス
  • コンパクトストリング
  • NashornのパーサーAPI
  • Javadocの検索
  • HTML5 Javadoc

I will pickup these java 9 features one by one and update them with enough description and examples. That’s all about Java 9 features in brief with examples.

Source:
https://www.digitalocean.com/community/tutorials/java-9-features-with-examples