Javaを愛する25の理由
JetBrains はあらゆるプログラミング言語と、あらゆる種類の開発者を愛しています! 今月 2020 年 5 月に Java は 25 周年を迎えました! そのため、私たちはこの点に特別な注意を払い、Java と JVM について私たちが気に入っている 25 の項目を祝いたいと思います。
後方互換性
Java は最新バージョンの Java で 25 年前のコードを実行できるという点で他の言語とはほぼ異なっています。 言語開発者は後方互換性を非常に真剣に捉えていますが、これは多くの組織が Java を主要な開発プラットフォームとして採用しており、今後数年にわたって引き続き同じコードを JVM で実行できることを知っているためです。
成熟
長期間存在し続けてきたことには、多くのメリットがあります。 この 25 年間、開発者たちはさまざまな業界や業種、およびさまざまなプラットフォーム向けに Java でアプリケーションを書いてきました。 一方、開発者はこの 25 年間で Java を学校、大学、ブートキャンプ、および仕事で学習しています。 その結果、時間を掛けて学習してきた、継続的に成長する巨大な大規模なエコシステムが築かれました。 Java や Java が解決可能な数々の問題は、ベンダーや非営利組織、および個人によって詳細に文書化され、十分にサポートされています。 私たちのような開発者は、Java の成熟と広範な採用により、Java でコードを書きたい開発者に多くの仕事があるという事実を特に重要視しています。
絶え間ない改善
後方互換性や成熟度と対照的なのは、プラットフォームと言語の進化です。 2017 年(Java 9)以降は 6 カ月ごとに新しいリリースが提供され、この言語に対する変更や改善が確実に行われるようになりました。 この言語とプレビュー機能と組み合わせることで、新しい構文を実験し、開発者からフィードバックを受け、この言語を使用する人に非常に役立つ新機能を標準化することができます。
バランス
Java には後方互換性の維持と新機能の採用をバランス良く実現するという難しさがあります。 後方互換性を評価して 6 カ月ごとにリリースしつつ 3 年ごとに長期サポートリリースを提供するという今のやり方は、適切なバランスを維持できているようです。 この言語は廃止予定の非推奨機能を警告し、消滅する可能性のある機能に対する代替機能を用意するという方法で進化できています。
さらなる安定性を求める開発者は、長期サポートリリースを使い続けることができます。 このような開発者はアップグレード時のリスクを減らすため、6 カ月ごとのリリースに対して定期的にテストを実施することができます。6 カ月ごとにアップグレードしたい方はリリースのたびに Java の最新バージョンにアップデートできます。 新しい構文が標準化される前にそれを試したい開発者はプレビュー機能を有効化することができ、同じ事をいち早く行いたい方はまだリリースされていないバージョンの早期アクセスリリースを使用することもできます。Java の最新バージョンを使用しているチームは、あらゆるメリットを活かすことができます。
標準
標準は開発者にとって言語機能ほど刺激的なものではないかもしれませんが、Java、Java EE および Jakarta EE、さらには開発者がよく目にするユースケースに対応する標準があれば、開発者は楽に作業を行うことができます。データベースとの通信に JDBC を使用する方法が分かれば、データベースドライバーの実装方法を気にすることなく、常に同じ方法でデータベースを処理できます。JCP は Java の標準を定義するために使用される手続きの一つです。
Java 言語仕様では、Java 言語の概要とコンパイラの動作が説明されています。 この中では、JVM やハードウェアの種類を問わず、アプリケーションの挙動を予測するのに役立つ Java メモリモデルも取り上げられています。 Java 仮想マシンの仕様では、JVM の下位レベルの詳細が説明されています。 これらの仕様のおかげで、さまざまなベンダーが配布し、さまざまなプラットフォームで動作する JDK が指定された通りに、予測通りに動作できるようになっています。 その結果…。
Write Once Run Anywhere
WORA は Java の背景にある元のアイデアの一つであり、最近ではあまりにも当たり前になっているため、そもそも何が革新的だったのかを実感することもないかもしれません。 私は 2002 年にある非常に巨大な組織に勤務していた頃、旧来の技術スタックから Java に乗り換えたことを覚えています。組織内にはさまざまなハードウェアが大量に存在しており、アプリケーション専用のハードウェアを購入することなく新しい Java アプリケーションをそれらのハードウェアで実行できることが開発環境を全面的に Java に移行した主な理由の一つだったからです。 現在のようなクラウドの時代ではあまり関係が無いように思われるかもしれませんが、私たちが常に WORA を実際に目にしていないからといって、その恩恵を受けていないということにはなりません。 そしてもちろん、IntelliJ IDEA(または NetBeans)をお使いの方は、デスクトップ上で WORA の恩恵を受けています。
パフォーマンス
Java をあまり知らない方には驚かれることがありますが、Java は非常にパフォーマンスに優れた言語です。 Java は 25 年間にわたってパフォーマンスを改善してきた成熟したプラットフォームで、さまざまなパフォーマンスプロファイルを持つ多数のガベージコレクターが備わっており、JVM はほとんどの人間の開発者よりもはるかに適切に実際の本番環境でのユースケースに合わせて実行時にコードを最適化します。 例えば、Java はトランザクション遅延の少なさや、パフォーマンスが予測可能であることが重要である金融業界で広く使用されています。
ガベージコレクション
話は変わりますが、自動ガベージコレクションも 25 年が経った今では一般的に当たり前だと思われています。 アプリケーション内のメモリの割り当て方法や、解放方法を考える必要はありません。 各 JVM には 1 つ以上の異なるガベージコレクションのアルゴリズムが実装されているため、私たちは内部の挙動にあまり注意を傾けることなくアプリケーションに適したアルゴリズムを選択し、アプリケーションのビジネスロジックを書くことができます。
可観測性と管理
アプリケーションの動作に興味がある場合は、非常に多くのツールを利用することができます。 これらの多くは無料で提供されており、特にJava Flight Recorder と Mission Control は現在では OpenJDK(Java 11 以降)の一部になっています。 JMX のようなツールでは、アプリケーションを動的に管理することもできます。
Java 仮想マシン(JVM)
前述の機能の多くは JVM の機能ですが、それが Java 言語そのものとは別であることは明確にしておかなければなりません。 WORA、実行時の最適化、パフォーマンス、ベンダーの選択などこれまでに取り上げたものも含め、JVM を愛用する理由はたくさんありますが、その多くは標準や仕様があるおかげで可能となっています。 JVM が Java 言語そのものと切り離されていることも重要です。それにより、さまざまな言語をプラットフォーム上でビルドし、前述した JVM の優れた機能をすべて利用しながらさまざまな構文と言語機能を提供できるからです。
その他の JVM 言語
Java が Java 6 と Java 8 の間の落ち着いた数年間(Java 7 には優れた機能がありましたが、Java 開発者によっては重要なリリースとは思えませんでした)に生き残った、あるいは成功した理由の一つは、他の JVM 言語です。 JetBrains で愛用されているのは当然ながら Kotlin ですが、JVM は Groovy、Scala、Clojure、JRuby のような他の人気言語用や非常に多くの他の新しい言語や再実装された言語用のプラットフォームです。 多くの場合、これら言語と従来の Java との相互運用性がこの多様性を受け入れて活用するのに役立っています。
ライブラリとフレームワーク
膨大なライブラリとフレームワークを選択できることも注目せざるを得ない理由の一つです。これらの多くはオープンソースであり、自由に利用できます。 具体的なSpring や Spring Boot のような人気フレームワークを使用することで、小規模なサービスから複雑なエンタープライズアプリケーションまであらゆるものを簡単に作成することができます。 標準があれば、多くの場合、似たようなものを別の状況で使用する場合にライブラリを理解して使用するのは難しくありません。 Java が成熟し、コミュニティによってオープンソースが早期採用されることで、通常は標準的な問題に対する既存の解決策が存在し、分かりきった事を最初からやり直す必要がなくなっています。 また、このような解決策の多くは長期間にわたって利用されており、十分にテストが行われ、理解され、文書化されています。
ビルドツールと依存関係の管理
経験に乏しい開発者が、実行しようとするコードが明らかに必要としているクラスを含む不明な JAR ファイルをインターネットで検索する必要があった時代はもう過去のものとなりました。 特に Maven と Gradle はアプリケーションのビルドとデプロイを簡単にしただけでなく、プロジェクトを必要なすべての依存物と共に標準的な方法でセットアップできるようにしています。 そのため、新規プロジェクトでも既存プロジェクトでも簡単にコーディングを開始できます。 Maven Central や Bintray のような公開リポジトリのおかげで、ライブラリの検索(と公開)を単純明快に実行できるようになっています。
JUnit と自動化テスト
JUnit は 1997 年に作成されました。つまり、Java とほぼ同じくらい古いものです!JUnit は Java の世界でも圧倒的に最も一般的な自動化テストフレームワークであり、JUnit と TestNG の両方が IntelliJ IDEA に同梱されています。なぜならば、どんな新規 Java プロジェクトでもテストフレームワークが必要になると考えられたためです。 あらゆる種類の言語用の最新テストフレームワークは、現在私たちが JUnit では当たり前だと思っているアイデアに基づいている可能性が高いです。 Java コミュニティの自動化テストの文化は、この一つのライブラリから多大な恩恵を受けています。
各種 IDE
ここは IntelliJ IDEA のブログですので、IDE について触れるのを忘れるわけにはいきませんでした! Java の冗長性に IDE が必要だと考えている方であれ、Java が静的型付け言語であるために実際に IDE を大いに活用できると考えている方であれ、Java 開発者は実際に IDE を愛用しています(私たちも開発者を愛しています!)。 IDE を効率よく使用する方法を学習すれば(IntelliJ IDEA、Eclipse、または NetBeans のどれであっても)、コード補完やコード生成、テストの実行、デバッグ、ナビゲーション、およびその他多くの機能を使用することで開発者の生産性を大幅に向上させることができます。 Java 開発者は通常、IDE がもたらすメリットに非常に高い関心を持っています。
コミュニティ
Java のコミュニティは大規模で成熟しており、活気に満ちている友好的なコミュニティです。 世界中の多くの都市に Java ユーザーグループがあり、物理的なミートアップに参加できない場合のバーチャル Java ユーザーグループもあります。 Java チャンピオンは、Java や JVM の開発者にとって有益または興味深い情報を共有して有名になった Java の世界で認められている技術的リーダーです。 Java には OpenJDK を介した JDK 自体も含め、大きなオープンソースコミュニティーが存在します。 Java コミュニティは学習、教育、継続的な改善を重視しており、標準と「ベストプラクティス」に関心を持ち、これらを現実世界の環境に適用する方法を現実的に考えています。
人
コミュニティを構成しているのは言うまでもなく人ですが、私が開発者に Java に関して最も重視していることを尋ねたとき、その多くは自分たちの強い影響を与えた Java 世界の人物であると明確に回答しました。 このような人物は、同僚や講師のほか、Brian Goetz、Angie Jones、Georges Saab、Mala Gupta、Venkat Subramaniam のような人物まで多岐にわたっています。 中には私の名を挙げた人もいました。 個人的なことを言えば、私が Java の世界に足を踏み入れたのは Java を大学で学び、仕事がたくさんあったからです。しかし、私はさまざまな人物や彼らから受けた支援やサポートを気に入っているため、この世界にとどまっています。
Javadoc とドキュメント
Java は Javadoc を通じて API ドキュメントを同言語の重要部分に位置づけています。 3 種類のコメント(Javadoc、ブロックコメント、行コメント)は、開発者が残しているコメントの種類を明確に示します。 Javadoc は、開発者がメソッドを呼び出したり、クラスやパッケージを使用したりする他の開発者に有益なドキュメントを残すことを特に奨励しています。 開発者がライブラリやコード片に関する詳細なチュートリアル情報を見つけられない場合、通常は正しい方向に導いてくれる Javadoc が存在します。
また、Java エコシステムは一般的に開発者に高品質なドキュメントを期待している(および提供している)ようです。 オープンソースプロジェクトのコミット者になりそうな方は、Javadoc コメントやその他ドキュメントのプルリクエストを提出することをお勧めします。また、世界中の開発者が StackOverflow で質疑応答を行ったり、特定の問題の解決策についてブログを執筆したりしています。
オープンソース
Java コミュニティは早い段階でオープンソースを取り入れただけでなく、今や JDK 自体も OpenJDK 経由でオープンソースで提供されています。 オープンソース化によって複数のベンダーのほか、個人も簡単に関与して協力できるようになりました。 Java 自体のコードを見ることができるのも、魅力的です。 オープンソースコードは、私たちのような開発者がすでに複雑な問題について考え、解決するために尽力した人々から学習できる素晴らしい機会をもたらします。
無料
Java エコシステムで使用される Java プラットフォームや多くの人気ツールは、開発者に対して(あるいは営利組織に対してすら)利用料金を支払うことを要求していません。 Oracle が Java 11 でライセンス方式とサポートを変更した後でさえ、同社(および他の多くのベンダー)は引き続き無料で同言語を本番環境で利用できる手段を提供していました。 この記事で前述したオープンソースプロジェクト、ビルドツール、各種 IDE はすべて無料であるか、無料のオプションがあります。 このため、コーディングを始めようとしている開発者や、予算を注視しながらソフトウェアをビルドする必要のあるあらゆる規模の組織にとって、Java は魅力的に映ります。
オブジェクト指向
オブジェクト指向プログラミングは当然ながら唯一の選択肢ではなく、どんなパラダイムにもメリットとデメリットがあります。 Java は当初からオブジェクト指向言語として設計され、オブジェクト指向に対応したデザインパターンやその他のコーディングベストプラクティスの多くの例が Java で示されています。 オブジェクト指向プログラミング言語が必要な場合は、Java を真っ先に試すべきでしょう。
進化と適合
Java はかつて、そして今もオブジェクト指向プログラミング言語です。 しかし、関数型プログラミングのいくつかの概念(ラムダ式、不変データ構造など)をうまく取り入れ、オブジェクト指向パラダイムの中で見事に動作させています。 型推論(var など)により、静的型付け言語のメリットを引き続き活かすことができますが、ボイラープレートは少なくなります。 コンピューターサイエンスはまだ比較的若い分野ですが、それでも私たちが学習する内容は既存のツールに適用することができます。 Java(言語とそのエコシステム全体)は新しいトレンドと新しい「ベストプラクティス」に従い、さらには現実世界での動きを確認した結果を受けて絶え間なく成長し続けています。
Java は他の JVM 言語の構文やアイデアを利用し、従来の Java 世界に何が機能し、何が適合しない可能性があるかを判断しています。 JCP や OpenJDK といった、Java が進化して成長するのに使用しているプロセスやツールでさえも、この絶え間ない進化に対応し続けられるように自分自身を適合させています。 この進化と適合は、Java が慎重に対処しなければならないバランスの一つです。
可読性への注力
Java のコードは往々にして Java 以外のプログラマーにも読みやすいものになっています。 この言語は簡潔すぎず、冗長に書かれる傾向があるために読みやすくなっています。 この言語の開発者は、演算子のオーバーロードのような機能を実装していません。なぜならば、予期しない独自の挙動に狼狽しないことが重要だと考えられているからです。 この言語と各種フレームワークには「魔法」を回避する傾向があります。一部のフレームワークは開発者が特に指定しなくても必要な動作を行う Convention over configuration(「設定より規約」)のようなアプローチを採用しますが、これは確実に(例えば)アノテーションを使用するアスペクト指向プログラミングをたくさん実行する必要がなくなり、さらにはアノテーションをドキュメントや静的解析チェックに使用する頻度も少なくなります。 コミュニティは標準と「ベストプラクティス」を好む傾向があるため、Java のコードはまったく異なるプロジェクトであっても往々にして似たようなルールに従っています。
言語機能
これまで私たちが Java について気に入っている 23 の項目について説明してきましたが、機能レベルでは何も取り上げていません! 正直に言えば、25 個の機能に絞り込むのは非常に難しく感じられたからです。また、私たちが Java に関して気に入っている多くの点が常に構文や機能に関するものであるとは限らないためです。 開発者の意見に照らし、一部のお気に入り機能を讃えたいと思います。
- Collections API:長きにわたって私たちの役に立っています!
- コレクション用の便利なファクトリーメソッド:変更不可能なコレクションを非常に簡単に作成できます。
- Streams API:Collections API を補完する非常に優れた API であり、Java 8 以降も進化しているのが素晴らしいです。 並列ストリームにより、最新のハードウェアを活用する方法が新しく追加されました。
- ラムダ式:Streams API と併用すると特に便利ですが、単独で利用しても非常に便利です。
- Optional:あるメソッドが有効なオブジェクトを返さない可能性があることを表現するのに便利な方法です(また、NullPointerExceptions から保護する必要がなくなります!)。 Java 8 以降で Optional に改善が加えられるたびに本当に嬉しくなります。
- java.time:日付と時刻を処理する最新の API は待ち望まれていた改善内容です
- チェック例外:人はチェック例外派とランタイム例外派に二分されますが、少なくともチェック例外はそれを使用したい人のために存在しています。
- アノテーション:アノテーションは(特に)コンパイラーがチェックできるドキュメント、あるいはフレームワークが何らかの重労働を行うためのメモのようなものです。
- JShell:Java を REPL で実行できるようになりました
- var:型推論は妥当な使い方をすればコードのノイズを減らすのに役立ちます
- アクセス修飾子とモジュール機能:Java はどのコードがどのフィールド、メソッド、クラス、モジュールにアクセスできるかを簡単に(Java 9 以降はさらに簡単に)明示できるようにしています。
- switch 式:switch 式を使用しても美しさがほとんど損なわれなくなりました!
- 便利な NullPointerExceptions:優れた NullPointerException が気に入らない人などいるのでしょうか? 開発者は例外から null の発生箇所に関するより有益な情報を取得できるようになりました。
- プレビュー機能:私たちはプレビュー機能を愛用しています! また、Records、instanceof のパターンマッチング、テキストブロックに大いに期待しています。
今後の展望
現在、6 カ月ごとに新機能が提供され、毎回の長期サポートリリースでは通常、それを利用して実行しているアプリケーションに特に変更を加えなくてもパフォーマンスが向上します。 Java 15(2020 年 9 月)では、Hidden(非表示)クラス、テキストブロック(もはやプレビューではありません)、Records の最新プレビュー、instanceof のパターンマッチング、Sealed(シール)クラスのプレビューが実装される予定です。
また、将来的にはProject Loom による使いやすく、軽量な並行処理、Project Valhalla のインライン型、ラムダの痕跡のようなProject Amber からのさらなる言語の変更、プログラマーが外部 API にアクセスしやすくなる Project Panama、Project Leydon による起動時間の短縮、各種ガベージコレクターに対するさらなる改善などの実装も期待しています。
Java には明るい未来が待っています!
[原文] Original post in English is written by Trisha Gee