WisdomSoft - for your serial experiences.

1.1 Java仮想マシン

Java の概要と動作原理についての説明です。

1.1.1 なぜ、今Javaなのか?

本書で解説する Java 言語は Sun Microsystems 社が開発した James Gosling 氏設計の Java プラットフォーム専用のプログラミング言語です。

Java について学習する時、私たちは 「Java」 と 「Java言語」 をうまく使い分けなければなりません。Java という言葉は広い意味で使われますが、プログラミング言語としての Java を表す場合は、明確に Java 言語と表現しなければなりません。これは、Java がシステムとして独立している特殊な性質があるためです。

従来のアプリケーション・プログラムは、テキストで記述されたソースをコンパイラによって実行可能形式の機械語にコンパイルし、オペレーティング・システムがこれを起動して実行していました。C/C++ 言語プログラマーにとってはお馴染みの開発手法でしょう。しかし、情報技術が発達し、その関係が複雑化するごとに、これまでの手法による開発には生産性の限界が見え始めました。

プログラムは機械語でなければ実行することができませんが、機械語は特定の CPU やオペレーティング・システムに依存するため、互換性のない環境で実行することはできません。代表的な例では Microsoft の Windows 9x 系と Windows NT 系の互換性の問題などです。他のシステムへの移植などのなれば、問題はさらに深刻になります。それでも、複数のシステムを使い分けている利用者は、便利で使い慣れたプログラムを他のシステムでも使いたいと思うことでしょう。ところが、これを解決する方法は長い間存在しませんでした。開発者は、他のシステムにプログラムを移植する時、ソースプログラムを書き直す以外に方法がなかったのです。安価で強力な Windows 用アプリケーションがあったとしても、Linux 利用者は指をくわえて見ているしかありません。

Java は、これらの問題を解決する手段を開発者にも利用者にも提供してくれます。驚くべきことに、Java 言語で開発されたソフトウェアは、Java がサポートされているすべての環境で実行することができるのです。すなわち、Java の世界ではソースプログラムを一度書いたらどこでも動くということなのです。 これは、プログラマはもちろんですが、ソフトウェア開発企業にとっては大事件です。Windows 市場や Linux 市場という単位ではなく、パーソナルコンピュータ市場全体を対象とした開発が可能になるという事実は、ソフトウェアの開発コストを大幅に削減することが期待できるからです。

1.1.2 どこでも動くJavaの秘密

長年、多くの開発者が苦しめられたプラットフォームの壁を打ち破った Java の「どこでも動く」はどのように実現されているかが気になることでしょう。しかし、Java の技術は特別、新しいものというわけではありません。簡単に言ってしまえば、Java は BASIC やスクリプト言語で使われるインタプリタにすぎません。

商業的なソフトウェアの開発によく使われる C/C++ 言語は、人間が使う自然言語に近い形でプログラムを記述されたソースプログラム(原始プログラム)を、コンパイラという翻訳ソフトウェアを使ってコンピュータが直接認識することができるオブジェクトプログラムに変換し、さらにリンケージエディタという編集ソフトウェアによって、実行に必要なオブジェクトプログラムを結合して実行可能なロードモジュール(実行ファイル)を生成します。

図01 コンパイルの流れ
コンパイルの流れ

このような、コンパイラで翻訳するプログラミング言語をコンパイラ言語と呼びます。FORTRAN、COBOL、C/C++ 言語はこれに分類されます。コンパイラ言語は、最終的に機械語として実行できるため、実行環境に最適化される大きなメリットがあります。しかし、対話的な開発ができないことや、他のシステムでは実行できないこと、デバッグが容易ではないなどの欠点も存在します。

一方、ソースプログラムを文ごとに解釈し、翻訳と実行を同時進行で行うというプログラミング言語も存在します。この場合、インタプリタと呼ばれる翻訳実行ソフトウェアにソースプログラムを読み込ませて実行させなければなりません。

このような、インタプリタを使って実行するプログラミング言語をインタプリタ言語と呼びます。BASIC やブラウザに実装されているスクリプト言語、Perl 言語などが代表的でしょう。インタプリタ言語は実行システムを隠蔽することができるメリットがありますが、文の翻訳と実行を同時に行うため、実行速度が遅くなるという問題があります。

図02 インタプリタの流れ
インタプリタの流れ

例えるなら、コンパイル言語は外国語の文献を翻訳する作業に似ています。翻訳後の文書は元が外国語であったことを気にすることなく、スムーズに読み進めることができます。これに対して、インタプリタ言語は同時通訳です。通訳はネイティブな会話に比べればもどかしいものですが、リアルタイムな対話を行うために必要です。

ところが、Java はコンパイラとインタプリタの両方の特徴を備えています。Java 言語によって記述したソースプログラムはそのまま実行するのではなく、一度コンパイラを用いて Java 専用の機械語に翻訳します。そして、システムごと用意されている Java インタプリタで、コンパイラが出力したプログラムを読み込むことで実行されます。インタプリタさえ用意されていれば、CPU やオペレーティング・システムに関係なく実行することができるのです。コンパイラが出力する Java 専用の機械語をJavaバイトコードと呼び、これを読み取るインタプリタを Java仮想マシンと呼びます。

図03 Javaの実行手順
Javaの実行手順

Java はバイトコードの仕様を明確に定めているため、各システムで Java 仮想マシンを実装すれば、一度開発した Java プログラムはどのシステムでも同一の結果を保証してくれるという仕組みです(もちろん、Java 仮想マシンがなければ実行することは不可能である)。コンパイラを通すことで文字コードの問題や、実行時の構文解析で発生するオーバヘッドを避けることができるということも Java の大きな特徴です。Java はコンパイラ言語とインタプリタ言語の両方の特性を持つシステムなのです。

図04 抽象コンピュータの仕組み

つまり、一度 Java バイトコードを生成すれば、どのコンピュータでも Java 仮想マシンさえ実装されていれば同じ結果を得ることができるのです。バイトコードを生成したコンパイラの環境や、実際に実行するコンピュータの環境を意識する必要はありません。開発者は、Java を学習することで、あらゆる環境のソフトウェア開発手段を身につけることができるのです。Java バイトコードは Windows でも UNIX でも実行できますし、TRON コンピュータを搭載したハイテク家電製品や家庭用ゲーム機でも実行することができるのです。ただし、それらの環境で Java 仮想マシンが実装されていることが唯一の条件となります。