Java 8
機能インターフェイス
これは何ですか?関数型インターフェイスは、1 つの未実装 (抽象) メソッドを含むインターフェイスです。 @FunctionalInterface は、そのようなインターフェイスの上に配置されるオプションのアノテーションです。関数インターフェイス (抽象メソッドが 1 つだけある) の要件を満たしているかどうかを確認する必要があります。ただし、いつものように、いくつかの注意点があります。デフォルト メソッドと静的メソッドはこれらの要件に該当しません。したがって、そのようなメソッドが複数存在し、抽象メソッドが 1 つ存在する可能性があり、インターフェイスは機能します。また、インターフェイスの機能定義に影響を与えない Object クラスのメソッドが含まれる場合もあります。デフォルトメソッドと静的メソッドについて少し追加します。-
デフォルト修飾子を備えたメソッドを使用すると、既存の実装を壊さずに新しいメソッドをインターフェイスに追加できます。
public interface Something { default void someMethod { System.out.println("Some text......"); } }
はい、はい、実装されたメソッドをインターフェイスに追加します。このメソッドを実装するとき、それをオーバーライドすることはできませんが、継承されたメソッドとして使用します。しかし、クラスが特定のメソッドで 2 つのインターフェイスを実装している場合は、コンパイル エラーが発生します。また、クラスがインターフェイスを実装し、特定の同一のメソッドでクラスを継承している場合は、親クラスのメソッドがインターフェイス メソッドと重複して例外が機能しません。
-
インターフェイス内の静的メソッドは、クラス内の静的メソッドと同じように機能します。子孫クラスから静的メソッドを呼び出すことができないのと同様に、静的メソッドを継承することもできないことを忘れないでください。
-
Consumer - 型 T の引数を受け取り、何も返しません (void)。
例:
void someMethod(T t);
-
サプライヤー - 入力として何も受け取りませんが、値 T を返します。
例:
T someMethod();
-
関数 - T 型のパラメータを入力として受け取り、R 型の値を返します。
例:
R someMethod(T t);
-
UnaryOperator - T 引数を受け取り、型 T の値を返します。
例:
T someMethod(T t);
述語 - 値 T を引数として受け取り、ブール値を返します。
例:boolean someMethod(T t);
ストリーム
ストリームは、関数型スタイルでデータ構造を処理する方法です。通常、これらはコレクションです (ただし、あまり一般的ではない他の状況でも使用できます)。よりわかりやすい言葉で言えば、Stream は、for-each のような総当たり的な方法ではなく、すべてのデータを同時に処理するかのように処理するデータ ストリームです。小さな例を見てみましょう。フィルタリングする一連の数値 (50 未満) があり、5 ずつ増やし、残りの数値から最初の 4 つの数値をコンソールに出力するとします。これをもっと早くに行うにはどうすればよいでしょうか:List<Integer> list = Arrays.asList(46, 34, 24, 93, 91, 1, 34, 94);
int count = 0;
for (int x : list) {
if (x >= 50) continue;
x += 5;
count++;
if (count > 4) break;
System.out.print(x);
}
コードがあまり多くないようで、ロジックがすでに少し複雑になっています。ストリームを使用してどのように見えるかを見てみましょう。
Stream.of(46, 34, 24, 93, 91, 1, 34, 94)
.filter(x -> x < 50)
.map(x -> x + 5)
.limit(4)
.forEach(System.out::print);
ストリームはコードの量を減らし、コードを読みやすくすることで作業を大幅に簡素化します。このトピックについてさらに詳しく知りたい方のために、このトピックに関する優れた (優れているとさえ言える) 記事をここに示します。
ラムダ
おそらく最も重要で待望されている機能は、ラムダの登場です。 ラムダとは何ですか? これは、さまざまな場所に渡すことができるコードのブロックなので、後で必要に応じて何度でも実行できます。かなりややこしいですね。簡単に言えば、ラムダを使用すると、関数型インターフェイスのメソッド (匿名クラスの実装の一種) を実装できます。Runnable runnable = () -> { System.out.println("I'm running !");};
new Thread(runnable).start();
run() メソッドを不必要な煩雑な手続きなしで迅速に実装しました。そしてその通りです。Runnable は機能的なインターフェイスです。また、ストリームを操作するときにもラムダを使用します (上記のストリームの例のように)。かなり深く掘り下げることはできるので、あまり深くは説明しません。まだ根っからの探求者がさらに深く掘り下げることができるように、リンクをいくつか残しておきます。
- Habré に関する Java 8 のラムダ式に関する記事
- Alexander Kosarev のブログのJava のラムダ式に関する記事
フォーリーチ
Java 8 には、ストリームのようにデータ ストリームを操作する新しい foreach があります。以下に例を示します。List<Integer> someList = Arrays.asList(1, 3, 5, 7, 9);
someList.forEach(x -> System.out.println(x));
(someList.stream().foreach(…) に似ています)
メソッドリファレンス
参照メソッドは、Java クラスまたはオブジェクトの既存のメソッドまたはコンストラクターを :: 経由で参照するように設計された、新しく便利な構文です。メソッド参照には 4 つのタイプがあります。-
デザイナーへのリンク:
SomeObject obj = SomeObject::new
-
静的メソッドのリファレンス:
SomeObject::someStaticMethod
-
特定の型のオブジェクトの非静的メソッドへの参照:
SomeObject::someMethod
-
特定のオブジェクトの通常の (非静的) メソッドへの参照
obj::someMethod
someList.stream()
.map(String::toUpperCase)
.forEach(System.out::println);
参照方法についてさらに詳しく知りたい方は:
API時間
日付と時刻を操作するための新しいライブラリ java.time が追加されました。 新しい API は他の Joda-Time と似ています。この API の最も重要なセクションは次のとおりです。- LocalDateは特定の日付 (例: 2010-01-09) です。
- LocalTime - タイムゾーンを考慮した時間 - 19:45:55 (LocalDate に類似)。
- LocalDateTime - LocalDate + LocalTime の組み合わせ - 2020-01-04 15:37:47;
- ZoneId - タイムゾーンを表します。
- 時計- このタイプを使用すると、現在の時刻と日付にアクセスできます。
- Java と時間:ハブレに関するパート 1と2
- Java 8 の日付/時刻 API の概要
オプション
これはjava.utilパッケージの新しいクラスで、安全にnullを含めることができるという値ラッパーです。オプションの受信: Optional.ofOptional<String> someOptional = Optional.of("Something");
にnullを渡すと、お気に入りのNullPointerExceptionが発生します。そのような場合には、次のものが使用されます。 - このメソッドでは、null を恐れる必要はありません。次に、最初は空のオブジェクトを作成します。 オプション: 空かどうかを確認するには、次を使用します。 true または false が返されます。値がある場合は特定のアクションを実行し、値がない場合は何も実行しません: Optional が空の場合に渡された値を返すリバース メソッド (バックアップ プランのようなもの): 非常に長い間継続できます (幸いなことに、Optional は惜しみなくメソッドを追加しました) が、これについては詳しく説明しません。手始めに、いくつかのリンクを残しておくとよいでしょう。 Optional<String> someOptional = Optional.ofNullable("Something");
Optional<String> someOptional = Optional.empty();
someOptional.isPresent();
someOptional.ifPresent(System.out::println);
System.out.println(someOptional.orElse("Some default content"));
- Java オプション - holivars の父
- オプション: Java 8 のシュレディンガーの猫
- Java 8 の新しいオプション クラス (NullPointerException の万能薬ではない)
- Java 8 の機能: JavaRush 究極ガイド -パート 1および2 ;
- Habré の Java 8 の新機能。
- あまり語られていない Java 8 の機能トップ 10 ;
- Java 8 チュートリアル。
Java9
そこで、2017 年 9 月 21 日、世界は JDK 9 を目にしました。この Java 9 には豊富な機能セットが付属しています。新しい言語概念はありませんが、新しい API と診断コマンドは開発者にとって間違いなく興味深いものとなるでしょう。JShell (REPL - 読み取り-評価-印刷ループ)
これは対話型コンソールの Java 実装であり、機能をテストしたり、インターフェイス、クラス、列挙型、演算子などのコンソール内のさまざまな構成要素を使用したりするために使用されます。JShellを起動するには、ターミナルに jshell を記述するだけです。その後、想像力が許す限り何でも記述できます。JShell を使用すると、トップレベルのメソッドを作成し、同じセッション内でそれらを使用できます。これらのメソッドは、 staticキーワードを省略できることを除いて、静的メソッドと同様に機能します。詳細については、 Java 9. REPL (JShell) マニュアルを参照してください。プライベート
Java バージョン 9 以降、インターフェイスでプライベート メソッドを使用できるようになりました (アクセスが不十分なために他のメソッドをオーバーライドできないため、デフォルトおよび静的メソッド)。private static void someMethod(){}
try-with-resources
Try-With-Resources 例外を処理する機能がアップグレードされました。
BufferedReader reader = new BufferedReader(new FileReader("....."));
try (reader2) {
....
}
モジュール性 (ジグソー)
モジュールは、関連するパッケージおよびリソースと、新しいモジュール記述子ファイルのグループです。このアプローチは、コードの結合を緩和するために使用されます。疎結合は、コードの保守性と拡張性にとって重要な要素です。モジュール性はさまざまなレベルで実装されます。- プログラミング言語。
- 仮想マシン。
- 標準の Java API。
不変のコレクション
Java 9 では、コレクションを不変にしつつ、1 行でコレクションを作成して埋めることができるようになりました (以前は、不変コレクションを作成するには、コレクションを作成し、それにデータを入れて、メソッドを呼び出す必要がありました。たとえば、 Collections.unmodifiableList)。そのような作成の例:List someList = List.of("first","second","third");
その他の革新:
- Expanded オプション (新しいメソッドが追加されました)。
- ProcessHandle インターフェイスと ProcessHandle インターフェイスは、オペレーティング システムの動作を制御するように見えました。
- G1 - デフォルトのガベージ コレクター。
- HTTP/2 プロトコルと WebSocket の両方をサポートする HTTP クライアント。
- 拡張されたストリーム。
- Reactive Streams API フレームワーク (リアクティブ プログラミング用) を追加しました。
- Habré でのJava 9 のレビュー
- Java 9. 新機能は何ですか?
- Java 9: 新機能
- Java 9 - もうアップグレードしましたか? いいえ?そしてそれは必要ありません...!?
- Sander Mak が Java モジュールへの移行について語る
Java10
そのため、Java 9 のリリースから 6 か月後の 2018 年 3 月 (昨日のことのように覚えています)、Java 10 が登場しました。変数
これで、データ型を指定する必要がなくなりました。メッセージを var としてマークすると、コンパイラは右側に存在する初期化子の型によってメッセージの型を決定します。この機能は、初期化子を持つローカル変数でのみ使用できます。型を定義できる初期化子がないため、メソッドの引数、戻り値の型などには使用できません。var の例 (文字列型の場合):var message = "Some message…..";
System.out.println(message);
var はキーワードではありません。本質的には、 int と同様に予約された型名です。varの利点は大きく、型宣言は何のメリットももたらさずに多くの注目を集めますが、この機能により時間を節約できます。しかし同時に、変数がメソッドの長いチェーンから取得される場合、そこにどのような種類のオブジェクトがあるのかすぐに不明瞭になるため、コードは読みにくくなります。この機能をさらに詳しく知りたい人向け:
JITコンパイラ(GraalVM)
早速ですが、javac コマンドを実行すると、Java アプリケーションが Java コードから JVM バイトコード (アプリケーションのバイナリ表現) にコンパイルされることを思い出してください。しかし、通常のコンピュータ プロセッサは、JVM バイトコードを単純に実行することはできません。JVM プログラムが動作するには、このバイトコード用の別のコンパイラーが必要です。コンパイラーは、プロセッサーがすでに使用できるマシンコードに変換されます。javac と比較すると、このコンパイラーははるかに複雑ですが、高品質のマシンコードも生成します。現在、OpenJDKには HotSpot 仮想マシンが含まれており、これには 2 つの主要な JIT コンパイラが含まれています。1 つ目の C1 (クライアント コンパイラ) は、より高速な動作を目的として設計されていますが、コードの最適化が困難になります。2 つ目は C2 (サーバー コンパイラ) です。実行速度は低下しますが、コードはより最適化されます。どちらはいつ使用されますか? C1 は、長い JIT 一時停止が望ましくないデスクトップ アプリケーションに最適であり、C2 は、コンパイルにより多くの時間を費やすことがかなり耐えられる、長時間実行されるサーバー プログラムに最適です。 マルチレベル コンパイルでは、コンパイルが最初に C1 を通過し、結果が C2 を通過します (より高度な最適化に使用されます)。 GraalVM は、HotSpot を完全に置き換えるために作成されたプロジェクトです。Graal は、HotSpot 用の新しい JIT コンパイラーと新しい多言語仮想マシンなど、いくつかの関連プロジェクトとして考えることができます。この JIT コンパイラーの特徴は、Java で書かれていることです。Graal コンパイラの利点は安全性です。つまり、クラッシュではなく、メモリ リークではなく例外が発生します。また、優れた IDE サポートも提供され、デバッガー、プロファイラー、その他の便利なツールを使用できるようになります。さらに、コンパイラは HotSpot から独立している可能性があり、それ自体のより高速な JIT コンパイル済みバージョンを作成できるようになります。 採掘者向け:パラレル G1
G1 ガベージ コレクターが優れていることは間違いありませんが、シングル スレッドのフル GC サイクルを実行するという弱点もあります。未使用のオブジェクトを見つけるためにあらゆるハードウェアの能力が必要なときに、スレッドは 1 つに制限されます。Java 10 ではこの問題が修正され、GC は追加したすべてのリソースで動作するようになりました (つまり、マルチスレッドになります)。これを達成するために、言語開発者は GC からの主要なソースの分離を改善し、GC 用のきれいなインターフェイスを作成しました。この魅力の開発者である OpenJDK は、新しい GC の作成をできるだけ簡素化するだけでなく、アセンブリから不要な GC をすぐに無効にできるようにするために、特にコード内のダンプをクリーンアップする必要がありました。成功の主な基準の 1 つは、これらすべての改善を行った後に動作速度が低下しないことです。 こちらも見てみましょう: その他の革新:- クリーンなガベージ コレクター インターフェイスが導入されました。これにより、さまざまなガベージ コレクターからのソース コードの分離が向上し、代替コレクターを迅速かつ簡単に統合できるようになります。
- JDK ソースを 1 つのリポジトリに結合します。
- コレクションは、このコレクションの不変のコピーを返す新しいメソッドcopyOf (Collection)を受け取りました。
- オプション(およびそのバリアント) には、新しいメソッド.orElseThrow()があります。
- 今後、JVM は Docker コンテナ内で実行されていることを認識し、オペレーティング システム自体にクエリを実行するのではなく、コンテナ固有の設定を取得します。
- Java 10 ガイド
- Java 開発者が知っておくべき 10 の JDK 10 の機能
- Java 10 の新機能:パート 1と2
GO TO FULL VERSION