Q.6 本当に同じコードがどこでも動くのですか?

 Javaではプラットフォームの違いをJava仮想マシン(JVM)が吸収するため,基本的に同じクラス・ファイルが異なるプラットフォームで動作します。このため,Javaの移植性の高さを表す標語として「Write Once,Run Anywhere」という言葉が生まれました。「一度書けば,どこでも動く」という特徴をJavaのウリにしようとしたのです。

 しかし現実には,各種JVMの間の互換性やJVMの上に搭載されているフレームワークの種類の違いといった問題により,プラットフォームに応じてソースコードを修正しなければ動かないことが多々あります。これを皮肉った「Write Once,Test Anywhere(1度書いて,どこでもテストする)」という言葉もあるほどです。ただ,「テストして修正すれば動く」というのは,ほかの言語と比較するとはるかに高い移植性であることに間違いはありません。(米持)


Q.7 Javaでは開発者がメモリーを管理しなくていいと聞きましたが?

図2●世代別GCの基本的な考え方。メモリー空間を二つに分けて,それぞれの領域に対してGCを行う。何回かGCを実行しても回収されなかったオブジェクトは短命オブジェクト領域から長寿オブジェクト領域に移す

 Javaの実行環境であるJava仮想マシンは,「ガーベジ・コレクション(Garbage Collection,以下GC)」と呼ぶメモリー管理機能を備えています。ガーベジとはゴミのことで,不要になったメモリー空間,すなわち「ゴミ」を,プログラム実行中に回収(collection)して,再び利用できるようにするための仕組みです。

 GCには様々な方法があります。どのオブジェクトからも参照されていない“アクセス不能”なオブジェクトをゴミと判断して,そのオブジェクトが占めているメモリー領域を自動的に解放し,ほかの用途に使えるようにするというのがGCの基本的な考え方です。

 GCが不要になったメモリー空間を解放してくれるJavaに対して,C/C++言語では開発者がメモリー空間の取得,解放をプログラム中に明示的に指示してやる必要があります。そのため,JavaではC/C++に比べてメモリー管理周りのバグが発生しにくいとされています。Java以前にもSmalltalkやLispなどGCを備えたプログラミング言語がありました。しかしGCを備えて商業的に成功した言語はJavaが最初と言っていいでしょう。

 Javaが登場した当初は,GCを行う際にアプリケーションの実行をいったんすべて中断する「Stop The World」方式を採用していたため,GCが処理速度の低下を招いていました。近年では,「並行GC」「同時進行GC」「世代別GC」といった機構を取り入れることにより,アプリケーションをほとんど停止させることなく,不要なメモリー空間を高速に解放できるようになりました(図2[拡大表示])。(石原)


Q.8 Javaってアプリケーション開発が簡単なんですか?

 Javaは,誕生当初は,既存の言語(CやC++)に比べてアプリケーション開発が容易だと強調されていました。ただ最近では,企業システム向けのJava EEは難しいという声をよく聞きます。

 この状況に対応するため,Javaコミュニティは2003年ごろから「Ease of Development(EoD,開発を容易に)」というスローガンを強調しています。EoDの掛け声の下,言語仕様の簡素化,フレームワークの標準化,初級者向け開発ツールのリリースなどが行われています。難しいとの批判が多かったJava EEのEnterprise JavaBeans(EJB)も,次期バージョン3.0で批判意見を大胆に取り入れ,EoD路線への転換を図っています。(石原)


Q.9 Javaにはポインタはないですよね?

 「JavaにはC/C++で言うところのポインタという概念がありません」と書いてある解説書をたまに見かけますが,それは正確には間違っています。Javaからポインタに直接アクセスできないだけで,内部ではきちんとポインタを使っています。

 例えば,オブジェクトを生成するnew演算子を実行すると,戻り値として「参照値」と呼ばれるデータが返ってきて,参照変数に代入されます。参照値はnewで生成したオブジェクトそのものではなく,生成したオブジェクトの在り処を示す値ですから,実質上ポインタと同じ役割を果たしています。

 しかし,Javaの「参照値」に対してプログラム上で処理を行うことはできません。例えば参照値に対して,C/C++のポインタのように「10を足す」計算をしたり,0を代入するなど値を直接セットするといった操作はできないようになっています。

 Javaはポインタを「参照値」という概念で隠ぺいし,直接アクセスできないようにすることで安全性を高めているわけです。参照やガーベジ・コレクションといったJavaの機能は,バッファ・オーバーランなどによるデータ領域破壊やメモリー・リークなどのメモリー管理にまつわるトラブルを防止するのに役立っています。(米持)


Q.10 クラスライブラリって何のことですか?

 Javaのソースコードをコンパイルすると,クラスという単位でファイルに分かれてバイトコードに変換されます。このとき生成されるファイルがクラス・ファイルです。Java仮想マシンは,アプリケーションを実行するときに,必要なクラス・ファイルを組み合わせていきます。クラス・ファイルはいわばWindowsにおけるダイナミック・リンク・ライブラリ(DLL)のようなものです。

 クラスライブラリは基本的に,クラス・ファイルを集めたものです。ただし,クラス・ファイルを適当に寄せ集めたものはクラスライブラリとは呼びません。ある用途に適した,再利用性の高いクラス・ファイルを集めたものでなければなりません。例えば,アプリケーションを作るときに使うAPIを集めたものなどがクラスライブラリです。

 Javaではプログラムを配布するときに,関連があるクラス・ファイルをJAR(Java ARchive)という名前のZIPファイルにまとめることになっています(拡張子は「.jar」)。Javaのクラスライブラリは通常,Jarファイルとして提供されています。(米持)


Q.11 JREやJDKはJava仮想マシンとどんな関係があるのですか?

図3●Java仮想マシン(JVM),JRE,JDKの関係

 Javaプログラムが動作するには,実行環境であるJava仮想マシン(JVM)だけでなく,標準的なクラスライブラリ(APIとその実装)が必要です。こうしたプログラム実行に必要なソフトをパッケージ化したものが,Java Runtime Environment(JRE)です。すでにあるアプレットやJavaアプリケーションを動かしたいだけならJREで十分です。JREにコンパイラなど開発環境として必要なソフトを追加したパッケージがJava Development Kit(JDK)です(図3)。

 Windows,Linux,Solarisなど一般的なOS用のJREやJDKは,米Sun Microsystemsが無償で提供しています(http://java.sun.com/j2se/)。ほかに,米IBMなどのベンダーも,自社製プラットフォーム向けなどにJREやJDKを提供しています。(石原)