ハクソク

世界を動かす技術を、日本語で。

Java 26が登場しました

概要

  • Java 26がリリース、新機能は少なめだが今後の大きな進化の基盤を構築
  • Project Valhalla関連JEPへの準備が進行中
  • JEP 516JEP 522などパフォーマンスやGC改善が目玉
  • HTTP/3対応などコアライブラリの機能拡張
  • Java 25からの主な違いや利用例も紹介

Java 26の新機能まとめ

  • Java 26は新機能がやや控えめなリリース、今後の大規模アップデートのための基礎固め
  • Project Valhallaに関連するJEP(特にJEP 500, 529)への布石
  • 各JEPの概要、プレビュー状況、プロジェクト分類、追加機能、Java 25からの変更点を整理

Java 26で追加された主な新機能

  • JEP 516: Ahead-of-Time Object Caching with Any GC

    • あらゆるGCで利用可能なAOTオブジェクトキャッシュの提供
    • GC非依存フォーマットによるキャッシュ互換性向上
    • ZGCや大容量ヒープ環境で特に有効
    • -XX:+AOTStreamableObjectsオプションで強制利用も可能
    • 複数GCごとのキャッシュ管理コスト削減
  • JEP 522: G1 GC: Improve Throughput by Reducing Synchronization

    • G1 GCのスループット・レイテンシ改善
    • アプリケーションスレッドとGCスレッド間の同期削減
    • 2枚のカードテーブルを導入し、スレッド間干渉を回避
    • 書き込みバリアの簡素化による追加パフォーマンス向上
    • ヒープ1GBあたり約2MBの追加メモリ消費(0.2%)
  • JEP 517: HTTP/3 for the HTTP Client API

    • Java標準のHTTPクライアントAPIHTTP/3に対応

    • QUICプロトコルによる高速通信・マルチプレクシング

    • クライアントやリクエスト単位でHTTP/3利用を明示的に指定可能

    • サーバーが未対応の場合は自動でHTTP/2HTTP/1.1へフォールバック

    • プロトコルバージョンのネゴシエーションも自動で処理

    • サンプルコード:

      var http3Client = HttpClient.newBuilder().version(HttpClient.Version.HTTP_3).build();
      var http3Request = HttpRequest.newBuilder(URI.create("https://hanno.codes"))
        .version(HttpClient.Version.HTTP_3)
        .GET().build();
      

HotSpot関連の新機能

  • JEP 516: GC非依存AOTキャッシュ

    • オブジェクトのキャッシュフォーマットを論理インデックスベースに変更
    • ロード時にインデックスをメモリアドレスへ変換し再構築
    • ZGCや大規模ヒープ環境での起動高速化
    • コマンドラインオプションによる挙動制御
  • JEP 522: 2枚のカードテーブル

    • 書き込みバリアが非同期で動作し、同期コスト減
    • 高頻度でオブジェクト参照が書き換わるアプリで**5〜15%**のスループット向上
    • x64環境では追加で最大5%のパフォーマンス改善

Core Libs関連の新機能

  • JEP 517: HTTP/3対応
    • IETF標準のHTTP/3(2022年策定)、QUICベース
    • Java 11以降のHTTPクライアントAPIがバージョン指定でHTTP/3利用可能に
    • サーバー未対応時の自動フォールバック・プロトコルネゴシエーション

今後への布石

  • Project ValhallaのJEP登場に向けた基盤整備
  • Java 26の変更点は次期メジャー進化の準備段階
  • 詳細や追加情報は各JEPドキュメントを参照推奨

まとめ:

  • Java 26はパフォーマンス・基盤強化が中心
  • HTTP/3やGC周りの改善で実務的な恩恵も大きい
  • 近い将来の大型アップデートに備えた重要な一歩

Hackerたちの意見

最近、Javaのグリーンスレッドの代替がカラーファンクションを使ってないって知って、ちょっと驚いた。これでJavaの評価が上がったよ。
カラーファンクションって何?
「グリーンスレッド」って、一般的にこういうシステムが「非カラーだけど非同期っぽいパフォーマンス」として認識されることが多いかな。あるいは「ファイバー」とかね。それ以外だと「非同期」や「コルーチン」って呼ばれる。
グリーンスレッドとスタックレス非同期モデル、つまりasync/awaitを混同してるんじゃない?グリーンスレッドは色付きの関数を意味するわけじゃないよ。
色付きの関数は必要ないよ。だってJavaのグリーンスレッドは色付きの関数みたいにValueじゃなくてFutureを返すから。
ただ、関数の色付けを完全には解決してないんだよね。キャリアスレッドがピン留めされるのはまだ良くないし、非同期関数からブロッキング関数を呼び出すのも、色付けされたシステムでは良くないよ。
JEP 504: Applet APIの削除 これが削除されるのは嬉しいね。特にLinuxでのJavaプラグインは最悪だったし、企業のいろんなものに必要だったから。アイスティーウェブのこと覚えてる?機能的でオープンソースのJavaプラグインとJava Webstartの実装だよ。
アイスティーウェブのこと覚えてる?いやぁ、今でもそれを使ってる環境があるよ。
昔、Webstartの企業向けアプリをいくつか作ったことがある!インフラは結構良かったけど、ちゃんと動いた時だけね。それに、当時のJSよりずっと良かったし、IE6の時代だったから。
JavaプラグインとWebStartはずいぶん前に削除されたからね。APIが削除されたのは残念だな。クラスがいくつかあるだけなのに、今でも使われてるし。GitHubでJAppletを検索してみて。現代のブラウザでもWASMを使ってアプレットを実行したり、Java IDEのプラグインとして使ったりもできるよ。
Javaの世界から何年も離れてたけど、最近Android開発の要件で戻ってきた。訴訟の後、今のAndroid(Google)とJavaの関係はどうなってるの?Androidで26が期待できるのはいつ?それにしても、なんでAndroidはいつも遅れをとってるの?Kotlinが主流だから?それとももっと深い理由があるの?訴訟も影響してる?
Javaの主要な開発はOpenJDKで行われてる。Androidは独自のランタイム(Androidランタイムって名前が付いてる)を持ってて、Javaバイトコードは動かさず、自分たちのバイナリフォーマットを使ってる。JVMクラスファイルはそのフォーマットにコンパイルできるけど、サポートはいつもOpenJDKのJavaバージョンに遅れをとってる。Kotlinがプラットフォームのデファクト言語になった理由の一部は、当時サポートされてたJavaがすごく古くて、ラムダもなかったからなんだ。問題は、ほとんどのJavaライブラリがデスクトップ/サーバー、つまりOpenJDKのシーンに従いたがるけど、それだとAndroidと互換性がなくなるから、サポートするバージョンを上げるインセンティブがあったりするんだよね。
数十年前にJavaを使ってたことがあるんだけど(サーブレット覚えてる?)、今はFlutterを使ってAndroid開発ができるのが嬉しいよ。
天文学者は宇宙の年齢をナノ・ヴァルハラで測れると思う。毎年、完成に50%近づいている気がする…真面目な話、ゴーツさんとチームがやってくれたことには満足してるよ。シールドインターフェース(Java 17)と徹底的なスイッチ文(Java 21)のおかげで、ついにJavaにユニオンタイプが登場した!非同期/待機の流行に乗る代わりに、APIの重複を避ける一般的な解決策(仮想スレッド)ができたんだ。でもヴァルハラはほんとに長い道のりだったね。
確かにそうだね。同時に、プロジェクト・ヴァルハラはJVMにとって非常に長い間で最も重要な変化になるだろうし、将来において relevancy を保つための最高のチャンスだと思う。
JavaとJVMに関わってる人たちはすごく頭がいい。今や最高の言語になったし、業界用途ではGoよりも優れてると思う。Javaの欠点は常に文化だよね。物理学では進歩は古い物理学者が亡くなったときにしか起こらないって言うけど、Javaも同じで、文化が変わるのはそういうときだと思う。TypeScriptを使ってる人たち(Javaを使えるはずなのに、OOPやFactoryFactoryの宗教を受け入れないから異端者扱いされてる)もいるし。
「未来のためのしっかりした基盤」って、30年以上も続いている言語に対しては控えめな評価だよね。> 最高の言語になった って言うけど、俺には .net(ランタイム)やC#/F#(言語)に比べてかなり遅れをとってるように思える。Javaが追いつくとは思えないな。
「業界用途でGoよりも優れている」ってどういう意味?「業界用途」が何を指しているのか、JavaがGoよりもどの点で優れているのかがよくわからない(自分でもいくつか思いつくけど、君の視点を知りたい)。
C#を約13年使った後、Kotlinに移ったんだ。すごく美しい言語だよね。Javaのライブラリのドキュメントを読むと、なぜKotlinが好きなのかがわかる。Javaの文化は変わる必要はないと思うけど、Kotlinの簡潔さ(単純さではないけど)を中心に新しい文化が育っているし、Javaエコシステムのほとんどの利点を享受できるんだ。
どんどん良くなってるね。もう全部がSpring BootやJBossじゃなくてもいいし。クォークスやヘリドン、マイクロノートみたいな、もっとスリムでモダンなバックエンドフレームワークもあるし。スクリプト用のjbang(uvxやbunxみたいな感じ)、タムボUI(https://tamboui.dev/)でターミナルUIも作れるし、他にも色々あるよ。新しいJavaの機能も増えて、もっとシンプルなコードが書けるようになったしね。例えば、バーチャルスレッド、構造化された並行処理、ストリーム集約、パフォーマンスやリソースの改善とか。まだ完璧じゃないけど、これから数年でいい感じにまとまると思う。ただ、もっと良いビルドシステムが必要だね。GoやRustがやったことは正しかったから。
> OOPとFactoryFactoryの宗教を受け入れないことについて 今日はそうじゃないよ。もちろん、どの言語にもクソみたいなコード(または疑わしいパターン)はあるし、Javaコミュニティも早い段階でいくつかの革新をしてきたけど、今は違う状況だよ。FactoryFactoryはほとんど絶滅したし、見かけるのは「dailywtf.com」くらいだね。今は継承よりもコンポジションを好むことがわかってるし、ストリームAPIもある。言語とコミュニティは進化したから、古いパターンは同じ問題を解決するためにはもう必要ないよ。一例として、junit(テストライブラリ)のソースコードを見てみると、ぱっと見は教条的なOOPよりも手続き的な感じがするね: https://github.com/junit-team/junit-framework/blob/main/juni...
50年間で作られたプログラミング言語の煙が上がるフィールドを見つめて、最後に生き残った言語を眺めてる気がする。Javaは確実にその一つだよね。今、新しい言語を作る理由って何だろう?既存の言語は「十分良い」し、LLMが学習するための例がないと、新しい言語が tractionを得るのは難しいよ。昔、コンピュータを始めた頃にIBM/360アセンブラを学んだけど、数十年アセンブラを見てないな。でも、必要ならまだ viableな言語だと思う。Javaは勝ち残った(もちろん他にもたくさんの勝者がいるけど)、今はAIのバリケードが新しい参入者を止めようとしてる。私の予想では、50年後もJavaはここにあるだろうけど、人間がそれを作ることはないだろうね。
Javaには、なかなか負けない利点があるよね。Goよりもパフォーマンスが良くて、ビルドも速いし(人気のビルドツールを使わない限りだけど)、深い観察性を持ってるのがすごい。別の言語の方が好きだと思う人もいるかもしれないけど、最終的にJavaを選んだことを後悔する人の割合は、他の言語よりも少ないんじゃないかな。
これは好みの問題かもしれないけど、Java(やKotlin)のツールにはどうしても馴染めなかった。VimやHelixで主に作業してるけど、NixからTypeScript、Rust、Cまでほとんどの言語でうまくいくのに、Javaだけはなんかしっくりこなかった。ツール周りのDX(デベロッパーエクスペリエンス)もあまり良くない気がするし、Golangやnpmに比べると、JDK管理やGradleのもたつきが気になる。
> 産業用途ではGoよりも優れている でも、ベイエリアの人に聞いてみると、特に35歳以下の人たちは「Javaを使う?絶対無理」と言うだろうね。人々がいつも新しいものを追い求めるのは本当に面白い。
Goの開発者として、これはまさにその通りだと思う。最近Javaの良い話をよく聞くから、2012年以来初めてその言語をチェックしてみたんだ。そしたら、すごく感心した!言語のメンテナが多くの素晴らしい機能を追加しつつ、後方互換性も維持しているんだね。それに、JVMやガーベジコレクションも少しずつ改善されてる。ちょっと触ってみた後、個人プロジェクトをJavaで書くことにしたんだけど、1週間後には諦めてGoに戻った。ビルドツールはまだ過剰に設計されたゴチャゴチャだし、サードパーティのライブラリアピはひどいままだ。DjangoやRails、Goのエコシステムがあるのに、あのひどいSpringフレームワークを学ぶために5分も投資するつもりはないよ。コミュニティやオンラインフォーラム、オープンソースライブラリも、エンジニアリングや美的感覚に関して、全く異質で受け入れがたい感じがする。
Javaを15年以上使ってるけど、初期の頃のエンタープライズな機能や過剰な抽象化で嫌いになる人の気持ちもわかるよ。Springエコシステムと混同しちゃうこともあるしね。でも、Javaは年々進化してきた。今では多くの人が「モダンな」言語って呼ぶようになったし、冗長さも減ったし、ScalaやKotlinで魅力的だと思われる機能もたくさんある。GraalVMを使えばネイティブバイナリにもコンパイルできるから、JavaでCLIを作るのも現実的になったし、ラムダも使えるようになった。
バーチャルスレッドがないのが最大の問題だったね。これが協調マルチタスクの一般的なやり方をすごくダサくしてた。Goは最初からそれを持ってたのが大きなポイントだった。今、Javaもそれを手に入れたから、これで決まりかな?でも、JSは型の扱い方のおかげで、やっぱりボイラープレートが一番少ないだろうね。
最近Goのプロジェクトに取り組んで、ビルド時と起動時にもっと設定可能にするのが私の仕事だった(プラグインやアドオンを追加して、他のライブラリやツールから再利用できるようにする)。結局、*Factoryや*Providersを作らなきゃいけなかったんだけど、あんまりやりたくなかったんだ。すべてがハードコーディングされてると「AbstractFactoryProviderBuilder」を避けやすいけど、再利用可能で拡張可能にしようとすると、自分で書く羽目になると思うよ。
大学でJavaを学んでた時の傷がまだ残ってるよ。コーディングの楽しさが全部なくなっちゃって、結局Cを学ぶことになった。
Java 8の頃以来、Javaのマニュアルを読んでないんだけど、最近の変化についてキャッチアップするためにおすすめの本やリソースってある?
これが役に立つかもよ: https://www.marcobehler.com/guides/a-guide-to-java-versions-... https://advancedweb.hu/a-categorized-list-of-all-java-and-jv... こっちは参考資料みたいなものね: https://javaalmanac.io/
https://javaevolved.github.io/
Javaを1.4から使ってるけど、その頃から言語もエコシステムもかなり進化したよね。EJBの全盛期を耐え抜いたし、1.2が出たときにはSpringを取り入れた。OSGiバンドルを動かすためにIDEと何時間も格闘したこともあった。Swing/AWTでUIを作るのが嫌いだったけど、今でも使われてるものが多くて、徐々に素敵なJavaFXに置き換わってるね。12年前に書いたコードを見ると、自分も随分成長したなって驚くよ。
> Swing/AWTでUIを作るのが嫌いだったけど、今でも使われてるものが多くて、徐々に素敵なJavaFXに置き換わってるね。 そうそう、JFXは15年くらい前にJavaScriptにRIAsをもたらしたんだよね。Swing、JavaFX、SWTの3つの主要GUIツールキットの中で、Swingが最初にHighDPIサポートを得た(10年前だね)し、今でもIntelliJ IDEAや他のJetbrainsのIDEの基盤になってる。
変更点はどれも素晴らしいけど、文法についてはどう感じるか分からないな。もっとファーストクラスになってもいいはずのものが、そうなってないのが多い。`lazy`キーワードの代わりに`LazyConstant`が出てきたし、理由があるんだろうけど、詳しくは知らない。
ライブラリコードを進化させるのは簡単だよね。もしJavaが初期化子から定数の型を推論できるようになったら(新しいキーワードよりも理にかなってる)、見た目も良くてパワフルになると思う:private final LOG = lazy(logger(MyThing.class));