以前は、Java の新しいバージョンはめったにリリースされず、遅れも発生していました。現在、Oracle は「半年ごとに新しい Java」という自ら設定したリズムを維持することに成功しています。そこで数日前、厳密に予定通り、ついにJava SE 11とJDK (Java Development Kit) の実装を受け取りました。いつものように、新しいバージョンは古いバージョンと互換性があり、Java 11 のサポートは 2026 年 12 月までに終了します。
Java SE 11 の新機能 (開発者に表示)
Java では、JEP「JDK Enhancement Proposal」の実装を通じて変更が加えられることを思い出してください。JEP はOpenJDK を改善するための提案であり、承認、遅延、または拒否される可能性があります。つまり、本質的に、JEP のコレクションは OpenJDK の開発戦略です。新しい「機能」の前の角括弧内に、対応する JEP の番号を示します。 [323] ラムダ パラメータのローカル変数構文- ラムダ パラメータの var 構文 Java 10 では var キーワードが導入され、ローカル変数の型を明示的に指定しなくても済むようになりました。これによりコードが簡素化されました。JEP 323 では、ラムダ式を使用したこの構文の使用が拡張されています。簡単な例:list.stream ()
.map ((var s) -> s.toLowerCase ())
.collect (Collectors.toList ());
有名な Java エバンジェリストである Simon Ritterが書いている ように、経験豊富な Java プログラマーは、上記のコードは次のように置き換えることができるため、この場合に var を使用する必要がないことに気づくでしょう。
list.stream ()
.map (s -> s.toLowerCase ())
.collect (Collectors.toList ());
では、なぜ var をサポートするのでしょうか? 特殊なケースが 1 つだけあります。それは、ラムダ パラメータにアノテーションを追加する場合です。これは何らかの型が関与していないと実行できません。明示的な型を使用する必要を避けるために、次のように var を使用してすべてを簡素化できます。
list.stream ()
.map ((@ Notnull var s) -> s.toLowerCase ())
.collect (Collectors.toList ());
[330] 単一ファイルのソースコード プログラムの起動 Java ソース コードを含む単一ファイルとしてプログラムを起動できるように Java ランチャーを強化する Java は、その冗長な構文と、たとえ些細なアプリケーションであっても起動するための複数ステップの「儀式」のためにしばしば批判されます。時々、これが初心者を怖がらせることがあります。「 Hello World! 」を単に出力するアプリケーションを作成するには void
"、パブリック静的メイン メソッドを使用してクラスを作成し、 を使用する必要がありますSystem.out.println
。これを完了したら、 javacを使用してコードをコンパイルする必要があります。最後に、この後、アプリケーションを起動すると、不運な挨拶が表示されます (もちろん、IDEAとJavaRushに組み込まれた統合開発環境の両方が、この「アプリ起動の魔法」を独自に実行します - 編集者のメモ) )。正直に言うと、ほとんどのプログラミング言語では、プログラムを実行するための実際のスクリプトははるかに単純に見えます。JEP 330 では、単一ファイルのアプリケーションをコンパイルする必要がなくなるため、コマンド ラインを使用する場合は、次のように入力するだけで済みます。
java HelloWorld.java
Java ランチャーは、ファイルに Java ソース コードが含まれていることを検出し、コードを実行する前にクラス ファイルにコンパイルします。パラメータはソース コード ファイル名の前後に配置できます。名前の後に配置されたものは、アプリケーションの実行時にパラメーターとして渡されます。名前の前に配置されたものは、コードのコンパイル後にパラメータとして Java ランチャーに渡されます。コンパイラ固有のオプション (クラスパスなど) もコンパイルのためにjavacに渡されます。 例。ライン:
java -classpath / home / foo / java Hello.java Bonjour
は次の行と同等になります。
javac -classpath / home / foo / java Hello.java
java -classpath / home / foo / java Hello Bonjour
[321] HTTP クライアント (標準) - HTTP クライアント API サポートが標準化され、JDK 9 では、HTTP クライアント プロトコル (JEP 110)をサポートする新しいAPIが導入されました。JDK 9 ではJava Platform Module System (JPMS)も導入されたため、この API はインキュベーター モジュールとして組み込まれました(これらは、「ライブ」API が開発されている間、Java SE ではまだ標準になっていない新しい API を開発者に提供するモジュールです)削除の準備ができています - 開発者は新しい API を試し、フィードバックの提供を試みることができます)。必要な変更が加えられると (この API は JDK 10 で更新されています)、API を標準の一部にすることができます。したがって、HTTP クライアント API は Java SE 11 に正式に含まれるようになりました。これにより、 JDKの新しいモジュールとパッケージ java.net.http が導入されます。主な新しいタイプは次のとおりです。 HttpClient HttpRequest HttpResponse WebSocket この API は同期または非同期で使用できます。非同期モードでは、と が使用されます。 [320] Java EE および CORBA モジュールの削除Java の第 9 バージョンでのJava Platform Module System (JPMS)の導入により、モノリシックrt.jarファイルをいくつかのモジュールに分割できるようになりました。さらに、JPMS を使用すると、アプリケーションに必要なモジュールのみを含む Java ランタイム環境を作成でき、そのサイズを大幅に削減できます。透過的に定義されたモジュール境界により、Java API の廃止された部分を削除することがはるかに簡単になります - それが JEP 320 の機能です。java.se.eeメタモジュールには、Java SE 11 標準の一部ではないため、含まれない 6 つのモジュールが含まれていますJDK 内: CompletionFutures
CompletionStages
- コルバ
- 取引
- アクティベーション
- xml.バインド
- xml.ws
- xml.ws.アノテーション
新しい API
言語標準にHTTP クライアントモジュールとフライト レコーダモジュールが組み込まれたことにより、JDK 11 には多数の新しい API が登場しました。API の完全なリストについては、Gunnar Morling によってコンパイルされた、次のさまざまなバージョンの JDK の包括的な比較を参照してください。このメモでは、 java.net.http、jdk.jfr、およびjava.securityモジュールに含まれていないいくつかの新しいメソッドをリストします。 java.lang.String おそらく、JDK 11 API の String に対する最も重要な変更の 1 つであり、便利な新しいメソッドがいくつかあります。boolean isBlank ()
: 文字列が空であるかスペースのみが含まれている場合は true を返し、それ以外の場合は false を返します。Stream lines()
: この文字列から抽出された行のストリームを行終端文字で区切って返します。String repeat (int)
: int回繰り返された文字列を連結した値を持つ文字列を返します。String strip ()
: 最初の非スペース文字の前後のスペースをすべて削除した文字列を返します。String stripLeading ()
: 最初の非スペース文字までのすべてのスペースを削除した文字列を返します。String stripTrainling ()
: 最後の非スペース文字の後に出現するすべてのスペースを削除した文字列を返します。
strip()
このメソッドはすでに 同様のことを行っていますtrim ()
が、スペースによって、これらのメソッドは異なる意味を持ちます。場合によっては、trim()
スペースのみが切り取られ、strip()
タブなどの特殊文字も切り取られます。 java.lang.StringBuffer java.lang.StringBuilderこれらのクラスには両方とも、 /compareTo ()
を受け入れてを返す 新しいメソッドが含まれています。字句比較方法は新しい方法と似ています。 java.io.ByteArrayOutputStreamStringBuffer
StringBuilder
int
compareTo() CharSequence
void writeBytes (byte [])
: パラメータのすべてのバイトをjava.io.FileReader出力ストリームに書き込みます
Charset
。 java.io.FileWriter t を指定できる 4 つの新しいコンストラクターCharse
。 java.io.InputStream
io.InputStream nullInputStream ()
: を返しますInputStream
が、バイトは読み取られません。この方法をどのように使用するのでしょうか? これは、不要な出力を破棄したり、常にゼロバイトを返す入力を挿入したりするための /dev/null のようなものと考えることができます。
io.OutputStream nullOutputStream ()
io.Reader nullReader ()
io.Writer nullWriter ()
String toString (int)
: これは既存のメソッドのオーバーロードですが、char の代わりに int を使用します。
int compare (CharSequence, CharSequence)
: 2 つのインスタンスを辞書順に比較しますCharSequence
。最初のシーケンスが辞書順に 2 番目のシーケンスより小さい場合、等しい場合、または大きい場合は、それぞれ負の値、ゼロ、または正の値を返します。
lang.Object clone ()
: Java エバンジェリストの Simon Ritter は、この方法が混乱していることを認めています。このクラスは
Reference
インターフェイスを実装していないため
Cloneable
、このメソッドは常に例外をスローします
CloneNotSupportedException
。しかし、専門家はこの方法が将来何かに役立つことを示唆しています。
runFinalizersOnExit ()
これらのクラスの両方から削除されているため、互換性の問題が発生する可能性があることに注意してください。 java.lang.Threaddestroy ()
追加のメソッドはありません。削除された ことのみを説明しますstop (Throwable)
。ただしstop ()
、引数をとらない は引き続き使用できます。互換性の問題が発生する可能性があるため、この点に注意してください。 java.nio.ByteBuffer java.nio.CharBuffer java.nio.DoubleBuffer java.nio.FloatBuffer java.nio.LongBuffer java.nio.ShortBuffermismatch ()
これら すべてのクラスで、言語開発者は、このバッファと指定されたバッファの間の最初の不一致。 java.nio.channels.SelectionKey
int interestOpsAnd (int)
int interestOpsOr (int)
int select (java.util.function.Consumer, long)
: 対応するチャネルが I/O 操作の準備ができているキーのアクションを選択して実行します。長いパラメータはタイムアウトです。int select (java.util.function.Consumer)
: 上記の方法と同様に動作しますが、タイムアウトはありません。int selectNow (java.util.function.Consumer)
: 非ブロッキングである点を除いて、上記のメソッドと同様に機能します。
String readString (Path)
: ファイルからすべてのコンテンツを文字列に読み取り、UTF-8エンコーディングを使用してバイトを文字にデコードします。String readString (Path, Charset)
: 上記のメソッドと同様に動作しますが、 を使用してバイトを文字にデコードしますCharset
。Path writeString (Path, CharSequence, java.nio.file. OpenOption [])
: 一連の文字をファイルに書き込む場合CharSequence
、それらの文字はバイトにエンコードされます ( UTF-8を使用)。Path writeString (Path, CharSequence, java.nio.file. Charset, OpenOption [])
: は上記の方法と同様に機能し、文字のみが を使用してバイトにエンコードされますCharset
。
- Path(String, String[]): パス文字列または組み合わせてパス文字列を形成する文字列のシーケンスを変換して、パスを返します。
- パス (net.URI): URI を変換してパスを返します。
Object [] toArray (java.util.function.IntFunction)
: 提供されたジェネレーター関数を使用して、返された配列を配布し、このコレクション内のすべての要素を含む配列を返します。
void forEach (java.util.function.Consumer)
:すべての要素が処理されるか、アクションが例外をスローするまで、各Iterable要素に対して指定されたアクションを実行します。boolean removeAll (java.util.Collection)
: 指定されたコレクションにも含まれるこのコレクションのすべての要素を削除します (オプションの操作)。boolean removeIf (java.util.function.Predicate)
: 指定された述語を満たすこのコレクションのすべての要素を削除します。boolean retainAll (java.util.Collection)
: 指定されたコレクションに含まれるこのコレクション内の要素のみを保持します (オプションの操作)。
long convert (java.time.Duration)
: 指定された時間をこの単位に換算します。
Predicate not(Predicate)
: 指定された述語の否定である述語を返します。
lines.stream ()
.filter (s ->! s.isBlank ())
これに変換できます:
lines.stream ()
.filter (Predicate.not (String :: ISBLANK))
静的インポートを使用すると、次のようになります。
lines.stream ()
.filter (not(String :: ISBLANK))
java.util.Optional java.util.OptionalInt java.util.OptionalDouble java.util.OptionalLong
boolean isEmpty ()
:値がない場合はtrue 、それ以外の場合はfalseを返します。
Predicate asMatchPredicate ()
: Java 専門家 Simon Ritter は、ここに本物の JDK 11 API gem が隠されている可能性があると考えています。このメソッドは、このパターンが指定された入力文字列と一致するかどうかをチェックする述語を作成します。
int deflate (ByteBuffer)
: 入力データを圧縮し、指定されたバッファに圧縮データを書き込みます。int deflate (ByteBuffer, int)
: 入力データを圧縮し、指定されたバッファに圧縮データを書き込みます。圧縮データの実際の量を返します。void setDictionary (ByteBuffer)
: 指定された辞書が指定されたバッファ内のバイトに圧縮されるように設定します。ByteBuffer
これは、バイト配列ではなく を受け入れられるようになった既存のメソッドのオーバーロードです。void setInput (ByteBuffer)
:入力データを圧縮するように設定します。これは既存のメソッドのオーバーロードでもあります。
int inflate (ByteBuffer)
: 指定されたバッファにバイトをアンパックします。実際の非圧縮バイト数を返します。void setDictionary (ByteBuffer)
: 指定された辞書を指定されたバッファ内のバイトに設定します。既存のメソッドのオーバーロードされた形式です。void setInput (ByteBuffer)
:伸張する入力データを設定します。既存のメソッドのオーバーロードされた形式。
void addAll (Collection)
: コレクション内に存在するすべての要素を追加します。void addAll (int, Collection)
: 指定されたインデックスから開始して、コレクション内に存在するすべての要素を追加します。
int [] getSelectedIndices ()
: 選択したモデル内の選択したすべてのインデックスの配列を昇順で返します。int getSelectedItemsCount ()
: 選択された項目の数を返します。
shell.JShellException getCause ()
: この EvalException によって提示された実行クライアントでスロー可能な理由を返します。理由が存在しないか不明な場合は null を返します。
Java 11 の開発者以外の機能
[181] ネストベースのアクセス制御 Java およびその他の言語は、内部クラスを通じてネストされたクラスをサポートします。これが機能するには、コンパイラが特定のトリックを実行する必要があります。例えば:public class Outer {
private int outerInt;
class Inner {
public void printOuterInt() {
System.out.println("Outer int = " + outerInt);
}
}
}
コンパイラはこれを変更して、コンパイル前に次のようなものを生成します。
public class Outer {
private int outerInt;
public int access$000() {
return outerInt;
}
}
class Inner$Outer {
Outer outer;
public void printOuterInt() {
System.out.println("Outer int = " + outer.access$000());
}
}
論理的には、内部クラスは外部クラスと同じコードの一部ですが、別のクラスとしてコンパイルされます。したがって、この操作には合成結合メソッドが必要です。合成結合メソッドは、外部クラスのプライベートフィールドへのアクセスを提供するためにコンパイラによって作成される必要があります。この JEP は、同じネストの 2 つのメンバー (この例では外側と内側) がネスト仲間であるネストの概念を導入します。クラス ファイル形式に対して、NestHostとNestMembersという 2 つの新しい属性が定義されています。これらの変更は、ネストされたクラスとバイトコードをサポートする他の言語に役立ちます。この関数は、 java.lang.Classの 3 つの新しいメソッドを導入します。 Class getNestHost () Class [] getNestMembers () boolean isNestmateOf (Class) [309] 動的クラス ファイル定数 この JEP は、新しいクラス ファイル形式をサポートするためのクラス ファイル形式の拡張について説明します。 CONSTANT_Dynamic 形式の永続プール。動的定数という考え方は矛盾しているように思えますが、本質的には Java 11 の最終値と考えることができます。 プーリング定数の値は (他の定数とは異なり) コンパイル時に設定されませんが、ブートストラップを使用します。リードタイムに価値を決定する方法。したがって、値は動的ですが、その値は一度だけ設定されるため、定数でもあります。この機能は主に、JVM 上で実行する出力としてバイトコードとクラス ファイルを生成する新しい言語とコンパイラを開発する人々を対象としています。 [315] Aarch64 組み込み関数の改善 この JEP は Red Hat コミュニティによって提案されました。JVM は、Arm 64 命令セットで利用可能なより特殊な命令を使用できるようになり、特に 、メソッド、sin ()
およびcos ()
java.lang.Mathlog ()
クラスのパフォーマンスが向上します。 [318] Epsilon: No-Op ガベージ コレクターJEP 315 と同様に、Epsilon ガベージ コレクターの導入について Red Hat に感謝することができます。イプシロンは、実際にはゴミを収集しないという点で珍しいです。新しいオブジェクトを作成するとき、必要に応じてメモリが割り当てられますが、未登録のオブジェクトによって占められていた領域は再利用されません。"ポイントは何ですか?"、 - あなたが尋ねる。この「ガベージ コレクション」には 2 つの用途があることがわかりました。
- まず第一に、このガベージ コレクターは、新しい GC アルゴリズムがパフォーマンスへの影響の観点から確実に評価されるように設計されています。アイデアは、Epsilon でサンプル アプリケーションを実行し、一連のメトリクスを生成することです。新しいガベージ コレクション アルゴリズムが有効になり、同じテストが実行され、結果が比較されます。
- ヒープに割り当てられたメモリを超えないことが保証できる非常に短いタスク (クラウドのサーバーレス機能を考えてください) の場合。これにより、アプリケーション コードのオーバーヘッド (コレクターを実行するかどうかを決定するために必要な統計の収集を含む) が排除され、パフォーマンスが向上します。ヒープ領域が使い果たされた場合、JVM は次の 3 つの方法のいずれかで誤って構成されている可能性があります。
- ノーマルを といいます
OutOfMemoryError
。 - ヒープリセットを実行する
- JVM ハード ドライブに障害が発生し、別のタスク (デバッガの起動など) を実行している可能性があります。
- ノーマルを といいます
- データをイベントとして生成および消費するための API を提供します
- バッファメカニズムとバイナリデータ形式を提供します
- イベントのカスタマイズとフィルタリングが可能
- OS、JVM HotSpot、および JDK ライブラリのイベントを提供する
GO TO FULL VERSION