JDK 16は昨日正式にリリースされ、新機能の早期採用者が登場します。

JDK 16は、2021年2月18日に最終候補バージョンを完成させ、2021年3月16日に正式にリリースされます。JDK 15と同様に、JDK16も短期バージョンで6か月しかサポートしません。2021年9月にリリースが予定されているJDK17は、ロングタームサポート(LTS)バージョンであり、数年間サポートされます。JDK 16は短期バージョンであり、ほとんどの企業またはプロジェクトは2018年9月にリリースされたJDK 11(または2014年3月初めにリリースされたJDK 8)に固執していますが、JavaerがJDKの新しいバージョンを作成することを妨げるものではありません。継続的な学習への情熱。

この記事は、JDK16で再生されます。

新機能のリスト


始める前に、JDK16バージョンによってもたらされる17の新機能を見てみましょう。

  この記事で解釈される機能

357:OpenJDKソースコードリポジトリがMercurialからGitに移行されました。この変更を促進するための努力は、バージョン管理システムのメタデータのサイズ、利用可能なツール、およびホスティングの点で利点を示します。

 

369:GitHubへの移行。この変更は、OpenJDKソースコードリポジトリのGitへの移行に基づいています。JDK16ソースコードリポジトリは、プログラマーにとって最も人気のあるソーシャルネットワーキングサイトに表示されます。

 

386:x64およびAArch64アーキテクチャで、JDKをAlpineLinuxおよびメインCライブラリとしてmuslを使用するその他のLinuxディストリビューションに移植します。Muslは、ISOCおよびPosix標準で説明されている標準ライブラリ関数のLinux実装です。Alpine Linuxは、イメージサイズが小さいため、クラウドデプロイメント、マイクロサービス、およびコンテナー環境で広く使用されています。LinuxバージョンのDockerコンテナイメージは6MB未満です。このような設定でJavaをすぐに実行し、Tomcat、Jetty、Spring、およびその他の一般的なフレームワークがこれらの環境で動作できるようにします。jlinkを使用してJavaランタイムのサイズを縮小することにより、ユーザーは特定のアプリケーションを実行するためのより小さなイメージを作成できます。

 

394:instanceof演算子のパターンマッチングは、JDK14およびJDK15でプレビューされており、JDK16で完成する予定です。パターンマッチングにより、プログラムの一般的なロジック(つまり、オブジェクトからのコンポーネントの条件付き抽出)をより簡潔かつ安全に表現できます。

 

395:不変データの透過的なキャリアとしてレコードタイプを提供します。

▐その他の  新機能

347:C ++ 14言語機能を有効にし、C ++ 14機能をJDKC ++ソースコードで使用できるようにし、HotSpotコードで使用できる機能に関する具体的なガイダンスを提供します。

 

376:ZGC(Scalable Low Latency Garbage Collector)スレッドスタック処理を安全なポイントから並行フェーズに移動します。ZGCガベージコレクターは、HotSpotでのGCの一時停止とスケーラビリティの問題を過去のものにするように設計されています。

 

380:Unixドメインソケットチャネルを追加します。ここで、Unixドメイン(AF_UNIX)ソケットサポートがnio.channelsパッケージのソケットチャネルおよびサーバーソケットチャネルAPIに追加されます。

 

387:柔軟なメタスペース機能により、未使用のHotSpot仮想マシンのクラスメタデータ(メタスペース)が占有するメモリをオペレーティングシステムにすばやく戻すことができるため、メタスペースの占有率が低下し、メタスペースのコードが簡素化されてメンテナンスコストが削減されます。

 

388:JDKをWindows / AArch64プラットフォームに移植します。

 

389:インキュベーション段階の外部リンカーAPIは、ネイティブコードへの静的タイプの純粋なJavaアクセスをサポートします。この計画の目的は、JNI(Java Native Interface)をより高度な純粋なJava開発モデルに置き換えて、C言語との対話を提供することです。そのパフォーマンスはJNIよりも優れています。

 

390:値ベースのクラスに対する警告の推奨事項:元のパッケージングクラスを値ベースのクラスとして指定し、そのコンストラクターを削除するために非推奨にし、新しい非推奨の警告を促します。Javaプラットフォームでは、値ベースのクラスのインスタンスを同期しようとする誤った試みは警告されます。

 

392:独立したJavaアプリケーションをパッケージ化するためのjpackageツールを提供します。

 

396:デフォルトでは、主要な内部API(misc.Unsafeなど)を除いて、JDKの内部構造は強力にカプセル化されています。この計画の目標には、JDKのセキュリティと保守性の向上、および開発者とエンドユーザーの両方がJavaの将来のバージョンに簡単にアップグレードできるように、開発者が内部要素の直接使用から標準APIの使用に徐々に移行することを奨励することが含まれます。

 

397:以前はJDK 15でプレビューされていました。JDK16の2番目のプレビューで封印されたクラスとインターフェースは、拡張または実装できるクラスとインターフェースを制限します。この計画の目標には、クラスまたはインターフェイスの作成者がそれを実装するコードを制御できるようにすること、アクセス修飾子よりも宣言的な方法を提供してスーパークラスの使用を制限すること、および基礎を提供することによってパターンマッチングの将来の開発をサポートすることが含まれます。パターン分析用。

 

338:インキュベーションフェーズのVector API(JDKにはインキュベーターモジュールが装備されます)、jdk.incubator.vectorは、サポートされているCPUアーキテクチャーで最高のハードウェア命令にコンパイルされたベクトル計算を表現し、同等のスカラー計算パフォーマンスよりも優れたパフォーマンスを実現します。

 

393:インキュベーション段階の外部メモリアクセスAPIにより、JavaプログラムはJavaヒープの外部の外部メモリ(ローカル、永続メディア、マネージヒープメモリを含む)に安全にアクセスできます。

 

新機能には、新機能の前にJDK拡張プロセスの識別子として番号が付けられています。詳細については、記事の最後にある「参考資料」を参照してください。

やってみよう


17の新機能を参照した後、JDK16とエンジニアリングに役立ついくつかの機能を試すのが待ちきれません。

次に、JDK公式Webサイト(http://jdk.java.net/16/)からJDK16候補バージョンをダウンロードします。

 

システム内の複数のJDKバージョンを簡単に切り替えるには、jenv(https://github.com/jenv/jenv)を使用できます。

ダウンロードしたJDK16パスをjenvに追加し、以下の設定で使用できます。

jenv add ${JDK16_Path}
jenv global openjdk64-16

すべてがうまくいけば、JDKのバージョンを確認すると、次の情報のようなリターンが返されます。

java -version
openjdk version "16"2021-03-16
OpenJDK Runtime Environment (build 16+36-2231)
OpenJDK 64-Bit Server VM (build 16+36-2231, mixed mode, sharing)

以前のバージョンのIDEAを開発ツールとして使用している場合、JDK 16を使用してプログラムを実行すると、次のエラーが発生する場合があります。

Cannot determine path to 'tools.jar' library for 16 (path/to/jdk-16) when running from IDEA, you should update to the latest version.

これは、JDK9がJavaランタイムをリファクタリングし、rt.jar、tools.jar、dt.jar、およびその他のさまざまな内部JARパッケージを削除したためです。ただし、以前の開発ツールは通常、このタイプのJARパッケージに依存しており、IDEAをアップグレードすることで解決できます。

公式ウェブサイトにアクセスして、IDEA 2021.1EAPのプレリリースバージョンを入手してください

(Https://www.jetbrains.com/zh-cn/idea/nextversion/)事前に体験してください(2021.3の公式バージョンを待つこともできます)。

新機能の解釈


▐GitHub  に移行する

早くも2020年9月、OpenJDKはGithubのjdkリポジトリをJDK16ソースコードのメインの読み取り/書き込みリポジトリとして使用していました。JDK 16の公式リリースにより、これはGithubでOpenJDKによって開発された最初のJDKバージョンになります。

 

OpenJDKソースコードリポジトリをMercurialからGitに移行するきっかけとなった3つの主な理由は、バージョン管理システムのメタデータ、利用可能なツール、利用可能なホスティングサイズです。

  • バージョン管理メタデータのサイズに関して、変換されたリポジトリの最初のプロトタイプは、バージョン管理メタデータのサイズの大幅な削減を示しています。たとえば、Gitを使用するjdkリポジトリの.gitディレクトリは約300MBですが、Mercurialを使用する.hgディレクトリは約1.2GBです。メタデータを減らすと、転送されるデータを減らしながら、ローカルディスクスペースを節約してクローン作成時間を短縮できます。

  • 利用可能なツールに関しては、GitにはMercurialよりも多くのツールがあります。すべてのテキストエディタは、ローカルまたはプラグインを介してGit統合を実装できます。さらに、Eclipse、Visual Studio、IDEAなど、ほぼすべてのIDEにGitが統合されています。

  • 利用可能なホスティングに関しては、セルフホストかサービスとしてホストされているかにかかわらず、Gitリポジトリをホストするための多くのオプションがあります。外部ソースコードホスティングプロバイダーを使用する理由には、パフォーマンス、開発者と対話するWeb APIのアクセス制御、および活発なコミュニティが含まれます。

OpenJDKがGithubに移行された後も、Java開発者にとってはまだ多くの便利さがあります。

  • JDK 16ソースコードリポジトリ(https://github.com/openjdk/jdk)をフォークすることで、メモを取りながらソースコードを読み取り、送信して、JDKソースコードの継続的な学習を容易にすることができます。Gitのアップスチームを使用して、JDKソースコードを最新の状態に保ちながら、それ自体も最新の状態に保ちます。

  • インターネットの速度が十分に速い場合は、Githubでコードをオンラインで読み取るためのツールであるGithub1s(https://github.com/conwnet/github1s)を使用し、ブラウザー(https:// github1s)でJDK16ソースコードをすばやく参照します。 .com / openjdk / jdk / releases / tag / jdk-16%2B35)も非常に便利です。

IDEAで作業および学習している場合は、JDK16ソースコードのクローンを作成します。

プロジェクト構造を開き(command +;)、ProjectSDKをJDK16に設定し、Project言語レベルを16に設定します。

その後、JDK16のソースコードを楽しく見ることができます。


▐JDKのAlpineLinuxへの  移植

クラウドネイティブの時代では、効率を改善するための個人的な理解が最初の原則です。

  • ミラーボリュームが小さいほど、配布時に高速になります

  • アプリケーション/コンテナの起動は高速である必要があります

これにより、システムの拡張が十分に速くなり、問題が発生したときにロールバックが迅速に処理されます。

さらに、コスト削減を考慮して、イメージボリュームが小さいほど、占有するメモリが少なくなり、配布中のリソースの消費量が少なくなります。

 

Alpine Linuxは、クラウドネイティブの効率改善の原則に適合する独立した非商用の汎用Linuxディストリビューションです。

これは、セキュリティ、シンプルさ、リソース効率に重点を置いており、musllibcとbusyboxを中心に構築されています。これにより、従来のGNU / Linuxディストリビューションよりも小さくなります。

JDKがAlpineLinuxに移植されると、Tomcat、Jetty、Spring、およびその他の一般的なフレームワークがJDKで動作できるようになります。ユーザーは、特定のアプリケーションを起動して実行するために、より小さなイメージを作成できます。

 

事前にDockerを準備し、最初にAlpine Linuxイメージをビルドし、次にJDK 16を追加し、最後に簡単なSpringBootプログラムを実行してデモンストレーションを行います。

▐AlpineLinux  イメージを構築する

# 获取Alpine Linux镜像
docker pull alpine
# 运行镜像
docker run alpine echo'Hello Alpine!'

docker imagesコマンドで画像サイズを確認すると、この記事の完成時点で、アルパインの画像サイズはわずか5.6MBであることがわかります。数十または数百MBのミラーを移動するdebian、ubuntu、centos、およびその他のシステムと比較すると、アルパインは本当に小さいです!

REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
alpine              latest              7731472c3f2a        7 weeks ago         5.61MB

▐Add JDK 16  

OpenJDKはjlink(JEP 282:https://openjdk.java.net/jeps/282)を使用してJavaランタイムのサイズを縮小します。DockerHubからイメージを取得できます。

16-jdk-alpine(https://hub.docker.com/_/openjdk?tab=tags&page=1&name=16-jdk-alpine&ordering=last_updated)。

または、次のDockerコマンド:

docker pull openjdk:16-jdk-alpine

▐Run春ブーツ  

まず、Spring Boot FatJarプログラムを準備します。これは、SpringBootの公式WebサイトからHelloWorldを入手できます。サンプルプログラム(https://spring.io/guides/gs/rest-service/)。

Dockerfileを作成し、openjdk:16-jdk-alpineを使用して、SpringBootプログラムを追加します。

FROM openjdk:16-jdk-alpine
VOLUME /tmp
ARG JAR_FILE
ADD ${JAR_FILE} app.jar
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]

▐ビルドして実行  

# 构建镜像,设置JAR_FILE参数指向Spring Boot程序Jar包路径
docker build --build-argJAR_FILE=target/rest-service-0.0.1-SNAPSHOT.jar -t alpine-jdk16-app:latest .
 
# 查看镜像
docker images
 
# 根据镜像,启动容器运行
# -d参数 后台运行
# -p参数 Spring Boot默认端口8080,映射到容器端口8080
docker run -d-p8080:8080 alpine-jdk16-app:latest
 
# 查看容器运行
docker ps
 
# 验证成功之后可以停止容器
docker stop${CONTAINER_ID}
 
# 访问应用
curl-w'\n' http://127.0.0.1:8080/greeting?name=jdk16

これまでのところ、AlpineLinuxシステムを介したJDK16ランタイムを使用したSpringBootが開始されており、通常どおりアクセスできます。

アルパインシステムのJDK16イメージのサイズは約321MBです。オラクルの公式Linuxバージョンイメージの467MBと比較して、30%以上の削減。

レコードクラス


JDK 14から、Recordレコードクラスのプレビュー機能が提供され、この機能はJDK16の永続的な機能になります。Recordクラスは、Javaが冗長すぎて形式的すぎるという苦情に応えて、不変データの透過的なキャリアです。この計画の目標には、単純な値のコレクションを表すオブジェクト指向コンストラクターの設計、開発者が動作を拡張するのではなく不変データのモデリングに集中できるようにすること、データ駆動型メソッド(equals()や属性アクセスなど)を自動的に実装することが含まれます。 )。

 

このタイプは、新しいバージョンのIDEAで作成できます。

Recordレコードクラスが宣言された後、コードを追加する必要はほとんどありません。一連の暗黙的な宣言により、コードは非常に簡潔になります。

  • 暗黙的に宣言されたプロパティ

  • 暗黙的に宣言されたコンストラクター

  • 暗黙的に宣言されたequals()、hashCode()、toString()

  • 属性のアクセサーは暗黙的に宣言されており、アクセサーの名前は属性の名前と同じです。

public record Point(int x, int y) {}

レコードレコードクラスはローカルクラス機能をサポートしているため、レコードを一時的に使用する必要がある場合は、次の定義と使用が非常に便利です。

List<Merchant>findTopMerchants(List<Merchant> merchants, int month) {
    // Local record
    record MerchantSales(Merchant merchant, double sales) {}
 
    // 使用MerchantSales Record类临时包装merchant和sales,方便做处理。
    return merchants.stream()
        .map(merchant ->new MerchantSales(merchant, computeSales(merchant, month)))
        .sorted((m1, m2) ->Double.compare(m2.sales(), m1.sales()))
        .map(MerchantSales::merchant)
        .collect(toList());
}

Recordレコードクラスは、JDKの外部のツールライブラリ(Tuple、Pairなど)によって提供されるタプル関数を置き換えることができ、以下で説明するパターンマッチング機能により、コードを非常に簡潔にすることができます。

▐パターンマッチング  


JDK 14以降、パターンマッチングのプレビュー機能が導入され、この機能はJDK16の永続的な機能にもなります。したがって、JDK 16は短期バージョンですが、将来のJDKバージョンでパターンマッチング機能を引き続き使用することを妨げるものではありません。

 

パターンマッチングの現在の段階は、1つのパターン(タイプパターン)と1つの言語構造(instanceof)に制限されていますが、これは完全な機能の一部にすぎません。それでも、冗長な強制がなくなり、冗長なコードが排除され、より重要なコードがより明確に注目され、隠れたバグが排除されるという大きなメリットがすでに得られています。

 

例えば:

開発中にオブジェクトを解析する必要がある場合は、次のような方法を使用します

if (obj instanceofString) {
    String s = (String) obj;
    ...
}

パターンマッチング後に同等のコードを使用します。

if (obj instanceofString s) {
    // 通过使用模式匹配可以直接使用s局部变量
    ...
}

コードはずっときれいに見えますか?

instanceofを使用してオブジェクトタイプを取得することは、条件付き抽出の形式です。オブジェクトタイプが取得された後、オブジェクトは常にそのタイプにキャストされます。

以前は、明示的な型変換はinstanceofの後に実行する必要がありました。これは面倒な操作です。これらの操作を組み合わせる利点は、簡潔にするだけでなく、instanceofと強制コードの切り取りと貼り付けという一般的なエラーの原因を排除することでもあります。 instanceofのタイプを変更した後、キャストタイプを変更することを忘れがちです。これにより、抜け穴の隠れ場所ができます。この問題を排除するためのinstanceofのパターンマッチングを通じて、このタイプのバグをすべて排除することもできます。

 

この種の「最初にチェックしてから強制変換」を行う必要があるもう1つの場所は、equalsメソッドです。

別の例を見てみましょう:

publicbooleanequals(Object o) {
    if (!(o instanceof Point))
        returnfalse;
    Point other = (Point) o;
    return x == other.x && y == other.y;
}

パターンマッチング後に同等のコードを使用します。

publicbooleanequals(Object o) {
    return (o instanceof Point other)
        && x == other.x && y == other.y;
}

このコードは同じ効果がありますが、制御フローステートメントを使用する代わりに、複合ブール式を使用して同等の条件を表現することしかできないため、より単純で簡単です。

 

特別な宣言位置を除いて、パターンが一致するバインド変数(上記のコード例のように、文字列のobj instanceofはバインド変数です)、そのスコープも「通常の」ローカル変数とは異なります。

たとえば、次のように書くことができます。

if (a instanceof Point p) {
    // p is in scope
    ...
} else {
    // p not in scope here
}
 
// p not in scope here
 
if (b instanceof Point p) {     // Sure!
        ...
}

この特別なスコープにより、if-elseマルチブランチの場合にバインド変数を自由に再宣言できます。また、将来のswitchでのケースを検討するのにも便利です。といった:

if (x instanceofInteger num) { ... }
elseif (x instanceofLong num) { ... }
elseif (x instanceofDouble num) { ... }

パターンマッチングがJavaコードのキャスト操作の99%を排除できる場合、それは間違いなく人気があります。しかし、これに限定されるものではありません。時間の経過とともに、より複雑な条件抽出を実行し、より複雑な方法を使用してパターンを結合し、パターンを使用できる他の構造を提供できる他のタイプのパターンが表示されます。現在恒久的にサポートされているRecordクラスと、プレビューおよびその他の関連機能の封印されたクラスにより、パターンマッチングにより、将来作成するコードを大幅に簡素化できるようになります。

終わり


この記事では、JDK 16バージョンによってもたらされた17の新機能から、エンジニアリング作業と学習に役立ついくつかの機能を抽出し、これらの機能をすばやく理解します。

 

ほとんどの企業またはプロジェクトは、機能インターフェイス、ラムダ式、メソッド参照など、JDK8の超豪華な新機能から派生したJDK8をまだ使用しています(JDK市場の80%を占め、完全に主流です)。コンストラクター参照、より強力なSteam API、インターフェースの機能強化、オプション、PermGenスペースの代わりにJVMのメタスペースなど。

 

また、現在の技術変化の速いペースに追いつくために、Javaは新しいものを導入し続けていることもわかります。

JDK 9以降、Javaバージョンのリリースは6か月に1回に変更されました。JDK11は長期サポートバージョンであり、JDK17は今年の後半にリリースされる予定です。

JDK 9〜JDK15には、次のようないくつかの重要な新機能もあります。

  • JDK 9モジュールシステム、JShellインタラクティブコマンドライン

  • JDK10ローカル変数型推論

  • JDK 11 ZGCトライアル、HTTPクライアントAPI、Steamおよびその他の拡張機能

  • JDK 12スイッチ式拡張、JMHに基づくマイクロベンチマークスイートのセットを追加

  • JDK 13 Socket APIリファクタリング、テキストブロック(複数行のテキスト)

  • JDK 14のより価値のあるNPEエラーメッセージ、JDK16機能の部分プレビュー

  • JDK15シールクラスやレコードクラスなどのJDK16機能のプレビュー

この迅速なバージョン反復戦略により、Javaを存続させ、開発者がJavaをより効率的かつ堅牢に使用できるようになることを願っています。

参照


  • JDK 16のステータス、リリーススケジュール、および新機能

    (http://openjdk.java.net/projects/jdk/16/)

  • JDK 16:Java16の新機能

    (https://www.infoworld.com/article/3569150/jdk-16-the-new-features-in-java-16.html)

  • JavaソースコードリポジトリがGithubに移行されました

    (https://www.infoworld.com/article/3569068/javas-move-to-github-set-for-september.html)

  • Alpine + OpenJDKイメージでSpringBootを実行する

    (https://blogs.oracle.com/developers/running-spring-boot-in-a-docker-container-on-openjdk,-oracle-jdk,-zulu-on-alpine-linux,-oracle-linux、 -ubuntu)

  • JEP 394:instanceofのパターンマッチング

    (https://openjdk.java.net/jeps/394)

  • JEP 395:記録

    (https://openjdk.java.net/jeps/395)

  • JEP 397:封印されたクラス(2回目のプレビュー)

    (https://openjdk.java.net/jeps/397)


  参加しませんか 

タオ部門のアーキテクチャチームへようこそ。AlibabaMobileMiddlewareの創設者、Dubboのコアメンバー、テクノロジーを愛し、テクノロジーを使用してビジネスを促進することを望んでいる小さなパートナーのグループなど、チームメンバーがここに集まります。

 

タオ部門のアーキテクチャチームは、タオ部門(Taobao、Tmallなど)のアーキテクチャのアップグレードを促進し、タオ部門とグループ全体に基本的なコア機能、製品、およびソリューションを提供することに取り組んでいます。

  • ビジネスの高可用性ソリューションとコア機能(洗練されたトラフィック制御Marconiプラットフォーム:適応フロー制御、分離と融合、高いサイト可用性:障害の自己修復、複数のコンピュータールーム、リモートディザスタリカバリおよびクイックを備えたビジネス向けの柔軟な高可用性ソリューションを提供しますカットフロー回復

  • 新世代のビジネス研究開発モデルFaaS(ワンストップ機能研究開発ガイアプラットフォーム)

  • 次世代ネットワークプロトコルQUICの実装と着陸

  • モバイルミドルウェア(APIゲートウェイMTop、アクセスレイヤーAServer、メッセージ/プッシュ、構成センターなど)

一緒に道部の基本プラットフォームの構築に参加するのを楽しみにしています〜

 

履歴書を???に送信します:Zebin [email protected]

(タオ部門アーキテクチャ-アプリケーションアーキテクチャリーダー)

✿拡張  読書

著者| Xiong Zheng(Eight Winds)  

編集|オレンジ

生産|アリババの新しい小売技術

おすすめ

転載: blog.csdn.net/Taobaojishu/article/details/114957783