← Spring コース
34. ソースが動くまで: javac と .class と JVM
ここからは、前のセクションの地図に出てきた部品を1つずつ掘り下げます。出発点は Java そのものです。Java のソース(Hello.java)は というコンパイラで Hello.class に変換され、 コマンドが起動する (Java 仮想マシン)がそれを読み込んで実行します。
の中身は CPU のではなく、JVM 向けの命令列であるです。先頭4バイトは と決まっていて、続く番号が対象の版を表します。Rust は機械語の実行ファイルを作り、Node はソースをそのまま node に渡します。Java はその中間で、を動かすには JVM が別に必要です。
javac の仕事は翻訳が中心です。手元の実測では、2 + 3 のような定数式は 5 に畳まれましたが、add(2, 3) という呼び出しはそのまま残りました。同じ処理を Rust のリリースビルドにかけると、5 が機械語に直接埋め込まれます。Java で機械語を作るのは実行時の側で、次のレッスンで扱います。 25 の javac が既定で作った .class は、JDK 22 の JVM では読み込めませんでした。
点線の付いた語はタップすると説明が出ます。用語集を開く →
Hello.java人が書くソース
javac Hello.java
Hello.classバイトコード。919 B、先頭は CAFEBABE
java Hello
JVMクラスを読み込み、バイトコードを実行する
JVM の無い環境では java: command not found- ・919 B は JDK 25(Temurin 25.0.4.1)の javac を既定のオプションで使ったときの値です。JDK 22 でも同じ大きさで、違いは版を表す番号(69 と 66)だけでした。下の実行可能コードは自分自身を読む処理を含むため、.class はこれより大きくなります
- ・同じ処理を Rust で cargo build --release すると 469,008 B の ELF 実行ファイル(aarch64 の機械語)になり、Node は 97 B の hello.js をそのまま node に渡します
- ・JVM の仕様書は、JVM は Java 言語のことは何も知らず、class ファイルという決まった形式だけを知っている、と書いています(JVMS SE 25 §1.2)
▶ サンプルコードを実行してみよう(自由に書き換えてOK)
Java
図やコードに出てくる用語(タップで説明)
サンプルコードで身につける(5本) →
学んだ概念を、素朴な例から実務寄りの例まで5つの具体例で確認します。
公式ドキュメントで詳しく ↗