Java

エンタープライズ開発で広く使われるオブジェクト指向言語で、JVM 上で動作しプラットフォーム非依存を実現する

プログラミング言語ランタイム
Java」の技術書を見る →

Java とは

Java は、Sun Microsystems (2010 年に Oracle が買収) が 1995 年に公開したオブジェクト指向言語で、JVM (Java Virtual Machine) 上で動作する。「Write Once, Run Anywhere」の理念で、コンパイルしたバイトコードがどの OS でも動作する。エンタープライズ開発、Android アプリ、ビッグデータ処理で広く使われている。

リリース周期と機能の導入版

Java は 10 以降、半年ごとに新バージョンが出る。多くのベンダーが長期サポート (LTS) を提供するのは 17 (2021 年 9 月)、21 (2023 年 9 月)、25 (2025 年 9 月) の系列で、2026 年 8 月時点の最新 LTS は 25、最新リリースは 26 (2026 年 3 月) である。非 LTS 版は次の版が出るまでの半年で更新が止まるため、本番運用では LTS を選ぶのが基本になる。

近代的な文法要素は「Java 21 の新機能」としてまとめて紹介されがちだが、正式版になった版は機能ごとに違う。

機能正式版になった JDK
Text Blocks (複数行文字列リテラル)15
Record (ボイラープレートなしのデータクラス)16
Sealed Classes (継承の制限)17
Virtual Threads (goroutine 相当の軽量スレッド)21
Pattern Matching for switch21
Record Patterns (レコードの分解)21

21 が節目として語られるのは、17 の次の LTS としてこれらが一度に揃った版だからである。17 から移行するとまとめて使えるようになる、という意味で理解しておくとよい。

// Record: ボイラープレートなしのデータクラス
record User(String id, String name, String email) {}

// Virtual Threads: 数百万の軽量スレッド
try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {
    executor.submit(() -> handleRequest(request));
}

// Pattern Matching
String describe(Object obj) {
    return switch (obj) {
        case Integer i when i > 0 -> "positive: " + i;
        case String s -> "string: " + s;
        case null -> "null";
        default -> "unknown";
    };
}

TypeScript / Go との比較

TypeScript / Go との主な違いを以下に比較する。

観点JavaTypeScriptGo
型システム静的 (名前的型付け)静的 (構造的型付け)静的 (名前的・interface のみ構造的)
実行環境JVMNode.js / Deno / Bun / ブラウザネイティブバイナリ
並行処理Virtual Threadsasync/awaitgoroutine
起動速度遅い (JVM 起動)速い速い
エコシステムMaven CentralnpmGo Modules
用途エンタープライズ、AndroidWeb アプリCLI、サーバー

Lambda での Java

Java の Lambdaコールドスタートが遅い (JVM の起動、クラスロード、フレームワークの初期化が積み上がって数秒に達する) のが課題である。SnapStart は初期化済みの実行環境のスナップショットを取っておき、そこから復元することでこの時間を縮める。

public class Handler implements RequestHandler<APIGatewayProxyRequestEvent, APIGatewayProxyResponseEvent> {
    public APIGatewayProxyResponseEvent handleRequest(APIGatewayProxyRequestEvent event, Context context) {
        return new APIGatewayProxyResponseEvent()
            .withStatusCode(200)
            .withBody("{\"message\": \"Hello\"}");
    }
}

SnapStart には制約が 3 点ある。発行済みのバージョン (とそれを指すエイリアス) でしか使えず $LATEST では有効にできない。プロビジョニング済み同時実行とは併用できない。そして 1 つのスナップショットが多数の実行環境の初期状態になるため、初期化フェーズで張った接続や、ID・シークレット・擬似乱数の種といった一意であるべき値は、復元後にハンドラー側で張り直す/作り直す必要がある。ここを見落とすと、複数インスタンスが同じ乱数列を返すといった再現しにくい不具合になる。

Spring Boot

Java のエンタープライズ開発で最も使われるフレームワーク。DI (依存性注入)、Web MVC、データアクセスを統合する。

GraalVM Native Image

GraalVM でネイティブバイナリにコンパイルすると、JVM の起動とクラスロードが実行時から消えるため、起動時間は数十ミリ秒の水準まで落ちる。

ただし代償がある。リフレクション、動的プロキシ、リソースの動的読み込みは事前に設定へ列挙しておく必要があり、漏れたクラスはコンパイルは通るのに実行時に落ちる。ビルドも通常の JVM 向けより桁違いに時間がかかる。加えて JIT による実行時最適化が効かないため、長時間動かし続けるサービスではピーク時のスループットが JVM 実行に劣る場合がある。起動の速さを最優先する用途で選ぶ手段であり、無条件の上位互換ではない。

Java を扱う関連書籍も多い。

この記事は役に立ちましたか?

関連用語

関連する記事