Java 9の機能と例
Java 9は重要なリリースであり、開発者に多くの機能をもたらしました。この記事では、Java 9の機能について詳しく見ていきます。
Java 10がリリースされました。Java 10のリリースの完全な概要については、Java 10の特徴をご確認ください。
Java9の機能
Java 9の重要な機能のいくつかは次のとおりです。
-
- Java 9のREPL(JShell)
-
- イミュータブルリスト、セット、マップ、およびマップエントリーのためのファクトリメソッド
-
- インターフェース内のプライベートメソッド
-
- Java 9のモジュールシステム
-
- プロセスAPIの改善
-
- リソースの自動解放の改善
-
- CompletableFuture APIの改善
-
- リアクティブストリーム
-
- 匿名内部クラスのダイヤモンド演算子
-
- Optionalクラスの改善
-
- ストリームAPIの改善
-
- 強化された@Deprecatedアノテーション
-
- HTTP 2クライアント
-
- マルチ解像度画像API
- その他のJava 9の機能
オラクル株式会社は、2017年3月末頃にJava SE 9をリリースする予定です。この記事では、「Java 9の特徴」について簡単に説明し、いくつかの例を示します。
Java 9のREPL(JShell)
オラクル株式会社は、「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の基礎(パート1)とJava 9 REPLの機能(パート2)を読んでください。
不変なリスト、セット、マップ、およびマップエントリーのためのファクトリーメソッド
オラクル株式会社は、Immutable List、Set、Map、Map.Entryオブジェクトを作成するための便利なファクトリーメソッドを導入しました。これらのユーティリティーメソッドは、空のまたは非空のコレクションオブジェクトを作成するために使用されます。Java SE 8およびそれ以前のバージョンでは、unmodifiableXXXのようなCollectionsクラスのユーティリティーメソッドを使用してImmutable Collectionオブジェクトを作成することができます。たとえば、Immutable Listを作成したい場合は、Collections.unmodifiableListメソッドを使用することができます。ただし、これらのCollections.unmodifiableXXXメソッドは手間がかかり冗長なアプローチです。このような問題を解決するために、オラクル株式会社はList、Set、Mapインターフェースにいくつかのユーティリティーメソッドを追加しました。ListとSetインターフェースには、以下に示すように、空のまたは非空のImmutable ListまたはSetオブジェクトを作成するための「of()」メソッドがあります。
空のリストの例:
List immutableList = List.of();
非空リストの例
List immutableList = List.of("one","two","three");
地図には、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}
これらのユーティリティメソッドについてもっと読みたい場合は、以下のリンクを参照してください。 (Korera no yūtiriti mesodemo motto yomitai baai wa, ikkō no rinku o sanshō shite kudasai.)
- Java 9 Factory Methods for Immutable List
- Java 9 Factory Methods for Immutable Set
- Java 9 Factory Methods for Immutable Map and Map.Entry
インターフェース内のプライベートメソッド
Java 8では、デフォルトメソッドと静的メソッドを使用してインターフェイス内でメソッドの実装を提供することができます。ただし、インターフェイス内にはプライベートメソッドを作成することはできません。冗長なコードを避け、再利用性を高めるために、Oracle CorpはJava SE 9インターフェイスでプライベートメソッドを導入する予定です。Java SE 9以降では、「private」キーワードを使用してインターフェイス内にプライベートメソッドとプライベート静的メソッドを記述することができます。これらのプライベートメソッドは他のクラスのプライベートメソッドと同様であり、その間には何の違いもありません。
public interface Card{
private Long createCardID(){
// Method implementation goes here.
}
private static void displayCardDetails(){
// Method implementation goes here.
}
}
もし新機能についてさらに詳しく読みたいなら、このリンクを通じて読んでください:Java 9におけるInterface内のPrivateメソッド。
Java 9のモジュールシステム
Java 9の大きな変更や機能の一つは、モジュールシステムです。Oracle CorpはJigsawプロジェクトの一環として、以下の機能を導入する予定です。
- Modular JDK
- Modular Java Source Code
- Modular Run-time Images
- Encapsulate Java Internal APIs
- Java Platform Module System
Java SE 9以前は、Javaベースのアプリケーションを開発するためにモノリシックなJarsを使用していました。このアーキテクチャには多くの制約や欠点があります。これらの制約を回避するために、Java SE 9ではモジュールシステムが導入されました。JDK 9には92のモジュールが含まれています(最終リリース時に変更される可能性があります)。以下に示すように、JDKモジュールを使用することも、独自のモジュールを作成することもできます:シンプルなモジュールの例。
module com.foo.bar { }
以下では、シンプルなモジュールを作成するために「モジュール」を使用しています。各モジュールには名前、関連するコード、およびその他のリソースがあります。この新しいアーキテクチャの詳細や実践的な経験についてもっと読みたい場合は、こちらのオリジナルのチュートリアルをご覧ください。
- Java 9 Module System Basics
- Java 9 Module Examples using command prompt
- Java 9 Hello World Module Example using Eclipse IDE
プロセスAPIの改善
Java SE 9では、Process APIにいくつかの改善が加わります。OSプロセスの制御と管理を簡単にするために、いくつかの新しいクラスとメソッドが追加されました。Process APIには2つの新しいインターフェースが追加されています。
- java.lang.ProcessHandle
- java.lang.ProcessHandle.Info
プロセス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("scdev.txt"));
try (BufferedReader reader2 = reader1) {
System.out.println(reader2.readLine());
}
}
Java 9の例を日本語で言い換えると、「Java 9の具体的な事例」となります。
void testARM_Java9() throws IOException{
BufferedReader reader1 = new BufferedReader(new FileReader("scdev.txt"));
try (reader1) {
System.out.println(reader1.readLine());
}
}
この新機能についてもっと詳しく読みたい場合は、Java 9のTry-With-Resources改善に関する私の元のチュートリアルをお読みください。
CompletableFuture APIの改善
Java SE 9では、オラクル株式会社はJava SE 8で発生したいくつかの問題を解決するため、CompletableFuture APIを改善する予定です。それには、遅延やタイムアウトのサポート、ユーティリティメソッド、そしてより優れたサブクラス化が含まれます。
Executor exe = CompletableFuture.delayedExecutor(50L, TimeUnit.SECONDS);
ここで、delayedExecutor()は、与えられた遅延時間後にタスクをデフォルトのエグゼキューターに送信する新しいエグゼキューターを返すために使用される静的なユーティリティメソッドです。
リアクティブストリーム
最近、美しい利点を得るためにアプリケーション開発でリアクティブプログラミングが非常に人気になっています。Scala、Play、Akkaなどのフレームワークはすでにリアクティブストリームを統合し、多くの利点を得ています。Oracle Corpsもまた、Java SE 9で新しいリアクティブストリームAPIを導入しています。Java SE 9のリアクティブストリームAPIは、Java言語を使用して非同期、スケーラブル、並行なアプリケーションを非常に簡単に実装するためのパブリッシュ/サブスクライブフレームワークです。Javaベースのアプリケーションでリアクティブストリームを開発するために、以下のAPIが導入されています。
- java.util.concurrent.Flow
- java.util.concurrent.Flow.Publisher
- java.util.concurrent.Flow.Subscriber
- java.util.concurrent.Flow.Processor
Java 9のリアクティブストリームで詳しく読む。
匿名内部クラスのためのダイヤモンド演算子
私たちは、Java SE 7でダイヤモンド演算子という新しい機能が導入され、冗長なコードを避けて言語の読みやすさを改善するために使われていることを知っています。しかし、Java SE 8では、オラクル社(Javaライブラリ開発者)がダイヤモンド演算子を匿名内部クラスと使う際の制限にいくつかの問題を見つけました。彼らはこれらの問題を修正し、それらをJava 9の一部としてリリースする予定です。
public List getEmployee(String empid){
// Code to get Employee details from Data Store
return new List(emp){ };
}
ここでは、型パラメータを指定せずに単に「リスト」を使用しています。
オプショナルクラスの改善策
Java SE9では、オラクル社はjava.util.Optionalクラスにいくつかの便利な新しいメソッドを追加しました。ここでは、その中の1つのメソッドについて、いくつかのシンプルな例を用いて説明します:streamメソッド。もしOptionalオブジェクトに値が存在する場合、このstream()メソッドはその値を持つ連続したストリームを返します。そうでなければ、空のストリームを返します。以下に示すように、Optionalオブジェクト上で遅延的に動作する”stream()”メソッドを追加しました。
Stream<Optional> emp = getEmployee(id)
Stream empStream = emp.flatMap(Optional::stream)
ここでは、Optional.stream()メソッドを使用して、EmployeeオブジェクトのOptionalのストリームをEmployeeのストリームに変換し、この結果を遅延評価で結果コードで使用できるようにしています。この機能や他のOptionalクラスに追加された新しいメソッドについて詳しく理解し、より多くの例を見るためには、元のチュートリアルを参照してください:Java SE 9:Optionalクラスの改善。
ストリーム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に関する情報を提供するために、このDeprecatedインターフェースにはforRemovalメソッドとsinceメソッドの2つのメソッドが追加されました。
HTTP 2 クライアント
Java SE 9では、オラクル社はHTTP/2プロトコルとWebSocketの機能をサポートするために、新しいHTTP 2クライアントAPIをリリースする予定です。既存のまたはレガシーのHTTPクライアントAPIには多くの問題があります(HTTP/1.1プロトコルをサポートせず、HTTP/2プロトコルやWebSocketをサポートしていない、ブロッキングモードのみで動作し、パフォーマンスの問題もあります)。このため、彼らはこのHttpURLConnection APIを新しいHTTPクライアントに置き換える予定です。彼らは新しいHTTP 2クライアントAPIを「java.net.http」パッケージの下に導入する予定です。それはHTTP/1.1とHTTP/2の両方をサポートしています。同期(ブロッキングモード)および非同期モードの両方をサポートしています。WebSocket APIを使用した非同期モードもサポートしています。この新しいAPIはhttps://download.java.net/java/jdk9/docs/api/java/net/http/package-summary.htmlで確認することができます。HTTP 2クライアントの例です。
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()))
以下のオプションで、ネイティブな日本語で述べられたパラフレーズを提供します:
HTTP/2プロトコルとWebSocketの理解には、Java SE 9: HTTP 2 Clientのオリジナルのチュートリアルをご参照ください。新しいAPIの利点と旧APIの欠点について、いくつかの有用な例を交えて説明しています。
マルチ解像度の画像API
Java SE 9で、オラクル株式会社は新しいマルチ解像度画像APIを導入する予定です。このAPIの重要なインターフェースはMultiResolutionImageです。このインターフェースは、java.awt.imageパッケージで利用できます。MultiResolutionImageは、異なる高さと幅(つまり、異なる解像度)を持つ一連の画像をカプセル化し、要件に応じてそれらをクエリすることができます。
Java 9のその他の機能
このセクションでは、いくつかのさまざまなJava SE 9の新機能をリストアップします。これらは重要な機能であるとは言っていませんが、理解するためには非常に重要であり、いくつかの有用な例を用いてよく理解することが重要です。現時点ではこれらの機能についての情報が十分に得られていません。それゆえ、簡単な理解のためにここにリストアップするようにします。これらの機能を一つずつ取り上げ、上記のセクションに簡単な議論と例を追加していきます。そして、後で別のチュートリアルを作成します。
- GC (Garbage Collector) Improvements
- Stack-Walking API
- Filter Incoming Serialization Data
- Deprecate the Applet API
- Indify String Concatenation
- Enhanced Method Handles
- Java Platform Logging API and Service
- Compact Strings
- Parser API for Nashorn
- Javadoc Search
- HTML5 Javadoc
Java 9の機能を一つずつ取り上げ、十分な説明と例を交えて更新します。これがJava 9の機能の簡潔な説明と例です。