「Windowsで作ったJavaのプログラムが、なぜMacやLinuxでもそのまま動くの?」――Javaを学び始めると、なんとなく動かしているうちに通り過ぎてしまう疑問です。この記事を読めば、その答えであるJVM(Java仮想マシン)の仕組みがわかります。
あわせて初心者が曖昧なまま進めがちな「.javaと.classの違い」「コンパイルとビルド」「パスとは何か」もスッキリ整理できます。
素朴な疑問:なぜJavaは「どこでも動く」のか
多くの言語では、作ったプログラムは動かすOSごとに作り直しが必要です。たとえばC言語では、コンパイル(プログラムを機械が実行できる形に変換すること)した結果がWindows用・Mac用などOSごとに別物になり、そのままでは他のOSで動きません。
ところがJavaは違い、一度書けばWindowsでもMacでもLinuxでも同じプログラムが動きます。これを「Write Once, Run Anywhere(一度書けば、どこでも動く)」と呼びます。その秘密が「バイトコード」と「JVM」です。
【全体像】Javaが動くまでの流れ
Javaのプログラムが実行されるまでには、大きく3つのステップがあります。
- 人が
Hello.java(ソースコード)を書く javacでコンパイルし、Hello.class(バイトコード)を生成する- 各OSにインストールされたJVMがバイトコードを翻訳して実行する

Hello.class はどのOSでも共通のファイルです。Windows用・Mac用・Linux用それぞれのJVMがそのファイルを読み込み、そのOSが理解できる形に翻訳して実行します。JVMがOSの違いを吸収するため、開発者は1つのプログラムを書くだけで済みます。
「どこでも動く」の前提として、実行するOS側にあらかじめJVM(JDKまたはJRE)がインストールされている必要があります。
ステップ1:.javaファイルとは(人が書くソースコード)
エディタやEclipseで書く public class Hello { ... } のようなコードが入ったファイルが .java ファイル(ソースコード)です。人が読み書きするための文章であり、コンピュータはこのままでは実行できません。
以下はもっともシンプルなソースコードの例です。
public class Hello {
public static void main(String[] args) {
System.out.println("Hello, World!");
}
}このファイルを Hello.java という名前で保存します。これが「ソースコード」です。
ステップ2:コンパイル(ビルド)で .classファイルに変換する
人が書いた .java をコンピュータ寄りの形に変換する作業がコンパイルです。Javaでは javac というコンパイラが担当し、.java から .class ファイルを作ります。
$ javac Hello.java # Hello.java → Hello.class が生成されるこの .class の中身が「バイトコード」です。人間にはほぼ読めない一方、特定のOSに依存しない「中間的な形」になっているのが最大のポイントです。
コンパイルにまつわる用語を整理しておきましょう。
| 用語 | 意味 |
|---|---|
| コンパイル | ソースコード(.java)を実行に向けた形(.class)に変換すること。担当は javac。 |
| バイトコード | コンパイルで生まれるOSに依存しない中間コード。.class の中身。 |
| ビルド | コンパイルを含む「実行できる状態に組み立てる一連の作業」の総称。小さなプログラムではほぼ「コンパイル=ビルド」でOK。 |
.java と .class の違いを表でまとめます。
| .javaファイル | .classファイル | |
|---|---|---|
| 中身 | 人が書いたソースコード | バイトコード(中間コード) |
| 読む相手 | 人間 | JVM |
| いつできる | 自分で書く | コンパイルで自動生成 |
| OS依存 | ― | しない(どのOSでも共通) |
Eclipseで javac を打った記憶がないのは、ファイルを保存するたびに裏で自動コンパイルしているからです。「いつのまにか .class ができている」のはこのためです。
ステップ3:JVMがバイトコードを各OS向けに翻訳して実行する
できあがった .class(バイトコード)を実際に動かすのが JVM(Java Virtual Machine=Java仮想マシン) です。JVMは共通のバイトコードを、その時動いているOSが理解できる機械語に翻訳しながら実行します。
$ java Hello # JVMが起動してバイトコードを実行ここが「Write Once, Run Anywhere」の核心です。JVMはOSごとに別々のものが用意されています。Windowsには Windows用、Macには Mac用のJVMがあります。だからプログラム(.class)は1つの共通ファイルのままでよく、OSの違いの吸収はJVMが引き受けます。結果、私たちはOSの違いを意識せず1つ書くだけで済みます。
「どこでも動く」とは正確には「JVMさえ入っていれば、どのOSでも同じ .class が動く」という意味です。バイトコード(.class)はそのままではどのOSも直接実行できず、翻訳役のJVMがいて初めて動きます。たとえばWindowsで作った .class を友人のMacで動かすには、そのMacにJVM(JDK/JRE)が必要です。
C言語と比べると違いがはっきりする
C言語との違いを比較すると、JVMの役割がより明確になります。
| C言語など | Java | |
|---|---|---|
| コンパイル結果 | OSごとに異なる実行ファイル | OS共通のバイトコード(.class) |
| 別OSで動かすには | OSごとに作り直し・再コンパイルが必要 | そのまま(各OSのJVMが動かす) |
| OSの違いの吸収 | 開発者が対応 | JVMが代わりに担う |
Javaは「OSごとの違い」をJVMという中間層に肩代わりさせることで、開発者をOSの差異から解放しています。
JDK・JRE・JVMの違いを整理する
この3つは入れ子(包含)の関係にあります。

| 名称 | 役割 | こんな人に必要 |
|---|---|---|
| JVM | バイトコードを実行する中核エンジン | (単体では使わない) |
| JRE | JVM+標準ライブラリ。Javaを「動かす」環境 | アプリを使うだけの人 |
| JDK | JRE+javacなどの開発ツール。Javaを「作る」環境 | プログラムを書く人(学習者) |
学習・開発でインストールするのはJDKです。JDKにはJREもJVMも含まれるため、「JDKを入れれば実行も開発もすべてできます」。Java 11以降はスタンドアロンのJRE単体配布が終了しており、基本的にJDKを入れる形が主流です。学習用はLTS版(執筆時点でJava 25のほか21・17)が安心です。
おまけ:パスとクラスパスとは?
環境構築でよく出てくる「パス」関連の用語も整理しておきます。
- PATH(パス):
javaやjavacなどのコマンドがどのフォルダにあるかをOSに教える設定。通っていないとjava: command not foundというエラーになります。 - クラスパス(classpath):JVMが
.classや外部ライブラリ(JAR)を探す場所を教える設定。ずれると「クラスが見つからない」エラーの原因になります。
ざっくりまとめると、PATHは「コマンドの置き場所」、クラスパスは「プログラム部品の置き場所」をOSに教えるものです。
例えるなら「共通語の台本」と「各国の通訳」
あなたが書く .java は日本語の脚本です。コンパイルすると世界共通語の台本(=バイトコード/.class)になります。各国の劇場には共通語を現地語に訳す通訳(=JVM)がいます。台本は1つでよく、あとは各劇場の通訳が訳します。だから同じ台本が世界中で上演できます。
C言語は最初から各国語で台本を書くようなものです。上演する国の数だけ書き直しが必要になります。
初心者がつまずきやすいポイント(よくある勘違い)
.classファイルを直接編集すればいい?
いいえ。.class はバイトコードであり、人が編集する形ではありません。修正は必ず .java 側で行い、再コンパイルして新しい .class を作ります。
JREだけ入れれば開発もできる?
できません。JREは「動かす」専用であり javac が含まれていません。ソースコードを書いてコンパイルするにはJDKが必要です。
Windowsで作った.classは本当にそのままMacで動く?
動きます。.class(バイトコード)はOSに依存しないため、Mac側にJVM(JDK/JRE)が入っていれば同じ .class をそのまま実行できます。
まとめ
.java(ソースコード)をコンパイルすると.class(バイトコード)になる- バイトコードはOSに依存しない共通の形
- JVMがバイトコードを各OSの機械語に翻訳して実行する(OSごとに専用のJVMがある)
- だからJavaは「一度書けばどこでも動く」を実現できる
- 開発で入れるのはJDK(JREもJVMも含まれている)
仕組みがわかったら次は手を動かしてみましょう。複数の .class を1つにまとめて配布・実行する方法はEclipseでJARファイルを作成・実行する方法で解説しています。
参考リソース
- Oracle公式「Java SE ドキュメント」:JVMやコンパイラの一次情報
- Oracle「Java SE サポート・ロードマップ」:LTSバージョンとサポート期間の最新情報
- EclipseでJARファイルを作成・実行する方法


コメント