Fascination N−D−File Java

戻る


いまどきのプログラム言語の作り方


プログラミング未経験者のための基本情報技術者
午後[プログラム言語]



やさしいJava 第3版(やさしいシリーズ)

Java(ジャバ)は、狭義ではオブジェクト指向プログラミング言語Javaであり、広義ではプログラミング言語Javaのプログラムの実行環境および開発環境をいう。 このJavaプログラムの実行環境と開発環境 (広義のJava) は、Javaプラットフォームとも呼ばれる。

Javaは、従来のさまざまな言語の良い部分を引き継ぎ、欠点を克服するよう設計された。 次のような特徴をもつ。

  • Javaではプラットフォームに依存しないアプリケーションソフトウェアの開発と配備を行うことができる。
  • Javaで開発されたソフトウェアは堅牢な実行環境 (仮想マシン) であるJava仮想マシンのもとで動作する。
  • オブジェクト指向プログラミングの考え方に基づいて設計された言語であり、ソフトウェアの開発と保守の複雑さを低減し、開発効率と保守性を高める。
  • Smalltalk や Objective-C と同様な簡潔なオブジェクトモデルを採用している。
  • 構文は C および C++ から多くを引き継いでいる。

現在、Javaの技術は、情報技術のローエンドからハイエンドまで幅広く使われている。 組み込みシステムや携帯機器(携帯電話・PHSやPDA・スマートフォン等)のシステムから、企業の情報システムを担う大規模なサーバやスーパーコンピュータまで、非常に多くの分野で活用されている。

概要

プログラミング言語JavaおよびJavaプラットフォームは、1990年代前半にサン・マイクロシステムズ社でジェームズ・ゴスリンなどの人々によって開発された。Java技術の標準化作業は、Java Community Process (JCP)というプロセスを経て行われている (#Java技術の標準化)。

Javaに関わる呼称とその意味内容は、文脈に応じていくつか使い分けられている。サン・マイクロシステムズは、「Javaテクノロジ」(Java技術、Java technology)という呼称を使い、一方でJavaのさまざまな技術の形容詞として「Java」の呼称を使ってきた。多くのプログラマは、プログラミング言語の意味で「Java」の呼称を使っている。Javaの実行環境は、Java実行環境 (Java Runtime Environment; JRE)と呼ばれる。Javaの基本的な開発環境は、Java開発キット (Java Development Kit; JDK)と呼ばれる。

Javaはクラスベースのオブジェクト指向プログラミング言語である (オブジェクト指向プログラミング)。Javaのプログラムは複数のクラスから構成され、プログラムの実行は、各クラスが実体化したオブジェクト群が相互にメッセージをやりとりしながら行われる。Javaでは、継承については実装の単一継承を採用している。ただし一つのクラス (オブジェクト) は複数のインタフェースを実装できる。Javaで扱うデータ/オブジェクトの型 (データ型) は、強い静的型付けを採用している。Javaのコンパイラおよび実行環境が、型同士の整合性を検査することによって、プログラムが正しく記述されていることや、安全に動作することの検証が、可能である。

Javaは例外処理機構を備えており、プログラム実行中に生じた異常 (例外) の扱いを、比較的安全な方法で行い、プログラムを読みやすく記述することができる。

Javaでは簡潔なメモリモデルを採用しており、プログラマがメモリ (主記憶装置) を管理する負担を軽減する (自動ガーベジコレクション) 。あらゆるオブジェクトはメモリ内のヒープという領域に割り当てられる。メモリ管理は、Java仮想マシンに統合された自動ガーベジコレクションの機能によって行われる。従来のオブジェクト指向プログラミング言語である C++では、ヒープ領域に生成したオブジェクトについて、もはや必要が無くなった時に破棄する指示を、プログラマが自分で責任をもって行わなければならなかった。これは、C++ プログラマにとっては負担が大きく複雑で間違えやすい作業であり、ソフトウェアの安全性・開発効率・保守性を損なう要因であった。Javaでは自動ガーベジコレクションの機能があるため、このようなことは無く、プログラマの負担は大きく軽減される。

Javaの文法は、CおよびC++から多くを引き継いでいる (文法) 。ただし、C/C++の低水準のポインタなどの要素は排除されている。

Javaではプラットフォーム非依存を目標の一つとし、またバージョン間の互換性に注意して開発が進められている (プラットフォーム非依存) 。Java技術を使うことで、プラットフォームに依存しないアプリケーションソフトウェアの開発と配備を行うことができる。従来のプログラミング言語の多くはプラットフォーム (CPU)に依存したネイティブなコードにコンパイルすることを前提として設計されていたが、Javaはこうした言語と異なり、中間言語 (バイトコード) にコンパイルされ、Java仮想マシンで実行されるよう設計された (多くの場合、ジャストインタイムコンパイル方式が使われる)。

プラットフォーム非依存とバージョン間の互換性の目標は、完全に達成できたわけではなく課題が残っている (Java批評#移植性・互換性) 。

Javaではスレッドを言語仕様で規定しており、マルチスレッドによる並列処理を、従来の言語と比べて簡単に実装することができる。なお並列処理は、複数の処理を同時に実行する処理形態である。またスレッドは、プロセスより小さく軽量な処理の単位である。

Javaでは充実したライブラリにより、コンピュータ・ネットワークを活用するソフトウェアを、効率良く開発することができる (ネットワーク機能) 。Javaの初期のバージョンから、TCP/IPのライブラリを備えていた。分散オブジェクト環境 (Java RMI、CORBA)のソフトウェアの開発も早い時期からできるようになっていた。近年では、さまざまなネットワークプロトコルの高水準なライブラリが使えるようになっている。充実したネットワーク機能と次に述べるXML文書を扱う機能を有効に組み合わせることにより、これまでにない高度なシステムの構築ができる言語の一つである。

XML文書を扱う機能も早期に実用化された。XMLは、広く普及している構造化文書の技術である。近年では、XMLプロセサとXSLTプロセサがJava標準ライブラリに統合され提供されている。

Javaはセキュリティを考慮して設計されており、サンドボックスモデルに基づいたセキュリティ機構を備えている (セキュリティ) 。セキュリティ機構を正しく実装したJava実行環境を適切に使うことで、遠隔のコンピュータ上にある実行コードを安全に実行することができる (Javaアプレット) 。

また、名前空間の機構をもつ言語であり、ライブラリおよびアプリケーションに含まれる多数のJavaのプログラム (クラスとインタフェース) は、パッケージという階層構造で管理することができる (名前空間) 。

現在、Javaの技術は、情報技術のさまざまな領域、ローエンドからハイエンドまで、幅広く使われている (近年の動向) 。携帯機器やウェブサーバ、企業の基幹となる情報システムにおいて、非常に普及している。パーソナルコンピュータ (PC)でも使われている。C++などの言語とともに、現在最も広く使われているオブジェクト指向プログラミング言語の一つである。

Javaに対しては批判も少なくない (批判) 。いくつかの批判に対しては、サンやJCPに参加する人々の努力により、Javaの改良が行われている。一方で現在、多くのソフトウェア開発者は、Javaについて、広く使われている言語としては優れた技術の一つと評価している。

JavaScript (ECMAScript)は、Javaとは直接の関係は無いが、Javaと似た言語名称と構文を持っている。

歴史

この節では次の構成で Java の歴史と近況を説明する。

  • 草創とインターネットの世界へで、Java の最初の正式なバージョンが公開されるまでの歴史を述べる。
  • 近年の動向で、その後から現在までの動向をいくつかの側面から述べる。
  • バージョン履歴で、最初のバージョン以降の Java (JDK、Java SE) のバージョンの履歴を述べる。

草創

Javaプラットフォームおよびプログラミング言語Javaは、1990年12月にサン・マイクロシステムズ社が一つの内部プロジェクトを立ち上げたことから始まった。 この内部プロジェクトでは、C++/C の代替となるプログラミング言語を開発した。 この言語は、プロジェクトで Greenオペレーティングシステム (Green OS) と共に、同OSの標準言語として開発された。 この言語は、1992年頃プロジェクト内では Oak と呼ばれていたが、後に Java の呼称に変更されることになる。 呼称変更の理由は、Oak は既に別の会社が商標として使っていたからである。

1990年頃、サンの技術者パトリック・ノートンは、自社のプログラミング言語 C++ と C の API (アプリケーションプログラミングインタフェース) と開発ツールに不満を募らせていた。 その頃、情報技術の世界でNeXT社が開発した技術が注目を浴びていたことがきっかけとなって、ノートンはサンで新技術の仕事をすることになった。

なお、NeXT社が開発したNeXTワークステーションとNEXTSTEPオペレーティングシステムでは、公式開発言語としてオブジェクト指向プログラミング言語 Objective-C を採用していた。

こうした経緯のなかで「ステルスプロジェクト」が始まった。

ステルスプロジェクトには、始まってすぐにジェームズ・ゴスリンとマイク・シェルダンが参加し、プロジェクトの名称は「グリーンプロジェクト」に変更された。 プロジェクトには他の技術者たちも参加し、彼らはアメリカ合衆国カリフォルニア州メンロパーク市サンドヒルロードの道沿いにある小さなオフィスで作業を始めた。 プロジェクトの目的は、次世代の家電製品のための新しいプログラミング技術を開発することであった。 サンはこの分野が重要な市場になると予測していた。

プロジェクトチームでは当初はプログラミング言語としてオブジェクト指向プログラミング言語である C++ を採用することを検討していたが、いくつかの理由から C++ は却下された。 彼らの目的は、家電製品すなわち組み込みシステムの技術を開発することであった。 組み込みシステムでは、利用できるコンピュータ資源が少ないという制約がある。 彼らは C++ ではコンピュータ資源を食いすぎると判断した。 また C++ は複雑なプログラミング言語であり、C++ を使うプログラマは注意していても間違いを犯しがちである。

C++ には自動ガーベジコレクションの機能が無い。自動ガーベジコレクションが無いということは、プログラマが自分でシステムのメモリを管理しなければならないことを意味する。プログラマが自分でシステムのメモリを管理することは、冒険的で間違いやすい作業である。

プロジェクトチームは、いくつかの重要な機能について C++ の移植性が乏しいことも問題であると考えた。 このプロジェクトでの重要な機能とは、セキュリティおよび分散コンピューティング、マルチスレッドであり、これらの機能が、プラットフォームに依存せずに使える必要があった。 このような事情で、彼らはあらゆる機器に容易に移植できるプラットフォームが必要であると認識するようになった。

一方で、サンの技術者ビル・ジョイは、プログラミング言語 MesaとCの良いとこどりをした新しいプログラミング言語を構想していた。 ジョイは Further という名前で呼ばれる論文を書き、自社で C++ に基づいたオブジェクト指向環境を開発するべきであることを進言した。 まずジェームズ・ゴスリンが C++ を改変し拡張することを試みた。 ゴスリンはこの拡張版C++を、"C++ ++ --" と名付けた。 しかしゴスリンは、すぐにこの拡張版C++の開発を中止して、全く新しいプログラミング言語を開発する方針を採ることにした。 ゴスリンはこの新しい言語に Oak という名前をつけた。 この名前の由来は、ゴスリンのオフィスのすぐそばにオーク (Oak) の木が立っていたことによる。

プロジェクトチームは残業までして作業を続け、1992年の夏までに新しいプラットフォームを、Greenオペレーティングシステム、Oak言語、ライブラリ、ハードウェアによって部分的なデモンストレーションができるようになった。 1992年9月3日の最初のデモンストレーションでは、チームは Star7というPDA (携帯情報端末) 機器を開発することに力点をおいていた。 このPDA機器は、グラフィカルなインタフェースを備え、"Duke" という名前の知的な仮想代理人が利用者を支援した。 同年11月、サンはグリーンプロジェクトを分離して完全子会社の FirstPerson, Inc を設立した。 それにともないチームはパロアルトに引っ越した。 FirstPersonチームは、高度にインタラクティブな機器に関心を持っていた。 そのおりタイム・ワーナー社がケーブルテレビのセットトップボックスの RFP (Request For Proposal) を公表していた。 そこでFirstPersonチームは自分たちの目標を変更し、タイム・ワーナーの RFP に応じてセットトップボックスの提案を提出した。 しかしながら、 FirstPersonは入札でシリコングラフィックス社 (SGI) に負けた。 その後に3DO社のセットトップボックスの案件もあったが、契約には至らなかった。 FirstPersonはテレビ業界では利益を出すことができず、サンはFirstPersonを解散してチームを自社に戻した。

インターネットの世界へ

1994年の6月から7月にかけて、ジョン・ゲージと、ジェームズ・ゴスリン、ビル・ジョイ、パトリック・ノートン、ウェイン・ロジン、エリック・シュミットの間で、3日間かけてブレインストーミングを行い、プロジェクトチームはウェブ (World Wide Web) の世界に主眼を置くという方針変更を行った。 彼らは、革新的なウェブブラウザである NCSA Mosaic の出現を目の当たりにし、ウェブを含むインターネットの世界は、ケーブルテレビの世界に劣らず、高度にインタラクティブな媒体に発展しつつあると認識するようになった。 Oak を使ったプロトタイプとして、ノートンは WebRunner という小さなウェブブラウザを開発した。 このウェブブラウザの名称は後に HotJava と変更された。 ウェブページにJavaアプレットという小さなJavaプログラムを埋め込んでおいて、ウェブブラウザ HotJava でそのページにアクセスすると、HotJava 上でアニメーションの表示やマウスによるインタラクティブな操作ができた。

同年、チームは Oak の名称を Java に変更した。 変更の理由は、商標を調べて、"Oak" という名前がすでにビデオカードアダプタの製造会社 (Oak Technology社) によって使われていたことが判明したからである。 Java という名称は、一部のチームメンバーがよく出入りしていた近くのコーヒーショップで命名された。 この名称が、何かの頭字語 (アクロニム) であるかどうかについては、よくわかっていない。

  • 頭字語ではないとの説が一般的に受け容れられている。
  • 近くのコーヒーショップで供されていたコーヒーのブランドに由来すると考える人が多い。その根拠は、Java のクラスファイル(中間言語のバイトコード)の最初の4バイトが必ず 0xCAFEBABE(十六進記数法)となっている事である (なお、プログラミングの世界ではこの 0xCAFEBABE のようなデータをマジックナンバーという) 。
  • また、米語においてはcoffeeを意味する一般名詞である。
  • ただし一部では、James Gosling, Arthur Van Hoff, and Andy Bechtolsheim の頭字語であるとの説がある。
  • また、Just Another Vague Acronym の頭字語との説もある。

1994年10月に、HotJava とJavaプラットフォームが、サン・マイクロシステムズの幹部社員の前でデモンストレーションされた。 そして1994年内に Java 1.0a (アルファ版) がダウンロードできるようになった。 Java と HotJava が最初に公的な場で公表されたのは、1995年5月23日のSunWorldカンファレンスであった。 サンは、Javaで記述されたウェブブラウザ HotJava を使って、JavaとJavaアプレットの技術により、ウェブページ内でアニメーションの表示やマウスによるインタラクティブな操作が可能であることをアピールした。 カンファレンスでアナウンスを行ったのは、サンの技術部長ジョン・ゲージである。 このカンファレンスではまた、ゲージのアナウンスに関連する、マーク・アンドリーセン (ネットスケープコミュニケーションズの上級副社長)によるアナウンスが人々を驚かせた。 それは、ネットスケープが自社のウェブブラウザである Netscape Navigator に Java の実行機能を追加する予定であるというものであった。 このアナウンスにより情報技術の世界でJava技術は広く知られるようになった。 1995年秋には Java 1.0 のベータ版が公開された。 1996年1月9日にサンは、Java技術の開発を行うJavaSoft部門を立ち上げた。 その2週間後に、最初の正式バージョンである Java 1.0 がリリースされた。

近年の動向

Java の最初のバージョンが公開されてから現在までの動向を、いくつかの側面から述べる。

ウェブ (クライアント側)

ウェブブラウザでJavaアプレットを実行する技術は、広く使われている。 Javaアプレットは、ブラウザ(ウェブのクライアント側)がウェブページ内でアニメーションの表示やマウスによるインタラクティブな操作を可能とする技術である。 ただし、いくつかの有力な競合技術も存在する。 近年では、Yahoo! Games やビデオプレイヤーなどのアプリケーションで、Javaアプレットを採用する事例が多い。

かつては、Javaアプレットを使用したサイトを表示すると、数十秒〜数分間操作を受け付けないブラウザが存在した。近年は、JavaおよびJavaアプレットの技術の向上により、環境によって動作が異なったり、実行速度、特に画面の描画が遅いという問題が解消されつつある。

簡単でインタラクティブなアニメーション用には、Javaアプレットよりも GIF89a や 有償のMacromedia Flash を採用する事例が多い。 この分野においては、最近では Ajax も普及しつつある。

ウェブ (サーバ側)

現在、ウェブのサーバ側において、Java技術 (Java EE) は広く使われている。 多くのウェブサイトが、Javaサーブレット (Java Servlet) や JSP (JavaServer Pages) などの Java EE 技術を使って動的にページを生成するウェブを構築している。 サーブレットは2000年前後から急速に広く使われるようになり、現在では多くのウェブアプリケーション(動的なウェブページ)がサーブレットとして稼動するようになっている。

サン・マイクロシステムズが開発したJavaサーブレット技術を簡単に説明する (必ずしも厳密な説明ではない) 。

  1. Java の実行環境のプロセス(サーブレットコンテナ)を起動してウェブサーバのマシンに常駐させる。
  2. ウェブサーバが、ウェブブラウザからアクセスされる(リクエストを受ける)。
  3. ウェブサーバは、そのリクエストをサーブレットコンテナに渡す。
  4. サーブレットコンテナで動くJavaプログラム (Javaサーブレット) は、受け取ったリクエストに基づき、ウェブページを動的に生成する。
  5. サーブレットコンテナは、サーブレットが生成したウェブページをウェブサーバに渡す。
  6. ウェブサーバは、サーブレットコンテナから受け取ったウェブページを、ウェブブラウザに返す。

サンがJavaサーブレット技術を開発した当時 (1990年代末) 、ウェブアプリケーションの開発には、次に述べるようないくつかの問題があった。

  • ウェブアプリケーション (動的なウェブページ) を記述するには CGI を用いるか、Microsoft IIS による ASP (Active Server Pages) を用いるのが大半であった。
  • CGI はその特性から実行時のオーバーヘッドが高く、性能を向上することが難しかった。
  • ASP はサーバが高価な Microsoft Windows NT Server である必要があった。

サーブレットはこれらの問題をある程度解決することができる技術であった。

デスクトップにおける展開

デスクトップ環境においては、スタンドアロンのJava (Java SE) のアプリケーションソフトウェア (Javaアプリケーション) は、これまではあまり多く使われていなかったが、近年はいくつかのソフトウェアが広く使われるようになっている。 近年になって使われるようになってきた理由としては、次のことが挙げられる。

  • コンピュータの処理性能が急速に向上してきた。
  • Javaの仮想マシン (Java仮想マシン、Java VM) とJavaコンパイラが大きく改良されてきた。
  • 使い勝手の良いJavaのデスクトップアプリケーションを簡単に開発できる強力な開発環境が、オープンソース界と商用開発企業の双方からさまざまなものが提供されるようになってきた。

広く使われているJavaのソフトウェアとしては、NetBeans および Eclipse の統合開発環境や、LimeWire や Azureus のようなファイル共有クライアントのソフトウェアなどがある。 また数学ソフトウェア MATLAB においても、ユーザインタフェースのレンダリングと計算機能の一部を実現するために使われている。 多くの Java の Swing や SWT のウィジェット・ツールキットを使ったアプリケーションが、現在も開発されている。

このように、近年はデスクトップ上でJavaアプリケーションを使う事例が増えつつあるものの、従来は次に述べるいくつかの理由のためにあまり使われてこなかった。

  • Javaアプリケーションは、Java実行環境のオーバーヘッドのため、ネイティブアプリケーションと比べて、大量のメモリを使うことが多い。
  • Javaアプリケーションのグラフィカルユーザインターフェース (GUI) は、実行対象となるプラットフォーム特有のヒューマンインタフェースガイドライン (HIG) を考慮しない傾向があった。HIG を考慮したアプリケーションを開発することによって、ユーザはアプリケーションをすぐに使い慣れることができる。また、デフォルトではフォントスムーシングが使えない。そのためユーザインタフェースの文字列 (テキスト) の表示の品質が低くなってしまう。
  • Java開発キット (JDK) として無償で提供される基本的な開発環境は、使い勝手の良いデスクトップアプリケーションを簡単に開発するには、力不足であった。
    近年では先述したとおり、使い勝手の良いJavaのデスクトップアプリケーションを簡単に開発できる強力なツールが、オープンソース/商用ともに提供され使えるようになっている。
  • Java実行環境 (JRE) はこれまで数度のメジャーバージョンアップを経ており、複数のバージョンが存在する。ユーザはJavaアプリケーションを使い始める際には、必要に応じて、そのアプリケーションが動くバージョン (もしくはそのバージョンより新しいバージョン) のJava実行環境をインストールする必要があった。Java実行環境は、7MB 以上のサイズであり、そのダウンロードとインストールもやや不便な手順をふむ必要があった。
    近年では Java Web Start の登場によりダウンロードとインストールも自動化され、ブラウザでJavaアプリケーションを見つけるとクリック一回でJREのダウンロード、インストール、アップデートなどをその場で済ませて Java Web Start 対応Swingアプリケーション実行できることが可能になり、現在あるJavaアプリケーションが Java Web Start 対応になってゆけば、これらの問題は解決される些細な問題になりつつある。

一部のソフトウェア開発者は、情報技術はウェブを基盤としたモデルが主流となっており、スタンドアロンアプリケーションは流行遅れであり、新しいプログラミング技術は優れたウェブアプリケーションを開発することに充てられている、と思っていた。この見解については、ソフトウェア技術者の間で賛否が分かれている。

現在では、リッチクライアントやWeb2.0の登場により新たなパラダイムが生まれようとしている。すなわちウェブを基盤としたウェブアプリケーションとスタンドアロンアプリケーションの融合である。ウェブアプリケーションをAjaxや Java Web Start、Adobe Flash などと組み合わせることにより、Web2.0時代に見合ったより洗練されたアプリケーションを開発することができる。

パーソナルコンピュータにおける実行環境

現在、ほとんどの パーソナルコンピュータ (PC) のユーザは、何ら問題なくウェブおよびデスクトップ環境上でJavaアプリケーションを実行できる。 多くのPCメーカーは、自分たちが製造・販売する Windows PC にJava実行環境 (Java SE) を同梱している。 アップルコンピュータ社の Mac OS X や、多くのLinuxディストリビューションでも、Java実行環境を同梱している。 そのため、マイクロソフト社が2001年頃以降にJava実行環境をWindowsに同梱していないことの影響は、小さい。

2001年頃にマイクロソフト社によるJava実行環境をWindowsに同梱することを止めたという行動は、サン・マイクロシステムズ社が同社を「品質の低い」Java実行環境を同梱してきたとして告訴したことが契機となった。マイクロソフト社がそれまでWindowsに同梱してきたJava実行環境向けに開発されたJavaプログラムは、他のプラットフォームのJava実行環境で動かない可能性があった。

しかし近年では、Javaアプリケーションパッケージ自体にJava実行環境を同梱する事例が少なくない。 その背景にはJavaアプリケーション開発者の判断がある。 Javaアプリケーションが想定どおりに機能するよう、Java実行環境のバージョンの違いによる非互換性に基づく不具合を避けるために、PCに同梱されているJava実行環境を使わないという判断である。

現在では、Javaアプレットは動作対象のJava実行環境のバージョンを認識することができる。 また、バージョン間の互換性もそこそこ高い水準にあり、上位互換性についてはjava SE 1.3以降は大きな問題はほぼおきにくくなっている。さらに Java Web Start ではデスクトップにインストールされているJavaのバージョンを確認してアップデートできるならアップデートし、それだけでなく Java Web Start 対応アプリケーションをもアップデートしようとする。 そのため古いバージョンのJava実行環境を使っているマシンがあったとしても、自動アップデートされるためにそう難しい問題は起きない。

組み込みシステム

組み込み機器 (組み込みシステム) 向けの Java (Java ME) も広く使われている。

携帯機器(携帯電話・PHSやPDA・スマートフォン等)にJavaの実行環境が実装されるケースが多い。 Java環境はこれら携帯機器全般に広く普及している。一方、 Symbian および BREWは携帯電話を主なターゲットとし、Javaと競合している。

Java ME では、BREW とは異なり、開発者がライセンス料を支払わずに、プログラムを開発することができる。 Java ME は Symbian より広く普及している。 その理由は、Java ME が Symbian より広範な携帯機器、特に廉価なモデルで動作するからである。 こうした事情からサードパーティにより Opera mini のようなフリーのJavaソフトウェアを開発することができるようになった。

携帯機器の Java ME プログラムは、サンドボックスのもとで動くため、多くの開発者が特別な配慮をせずにプログラムを開発しても、安全に実行できる。 携帯機器のJava技術が多様化するに伴い、異なるメーカーの携帯機器でもJavaプログラムが動くよう、携帯機器のためのJava技術の標準が必要となった。 携帯機器のための Java ME の標準が MIDP (Mobile Information Device Profile) である。 最初の標準は MIDP 1 で、小さい画面を想定したものであり、音声機能は無く、プログラムサイズは 32kB までという制限があった。 後の MIDP 2 の標準では、音声機能を備え、プログラムサイズの制限は 64kB までと緩和された。 携帯機器の設計の進歩は標準化よりも急速であるため、一部のメーカーは、MIDP 2 標準の最大プログラムサイズなどいくつかの制限を、意図的に緩和して携帯機器を開発している。

携帯機器における Java ME の競合技術について簡単に述べる。

  • Symbianの技術は、Symbian社が開発した携帯電話向けのユーザインタフェースフレームワークを備えたプラットフォームであり、マルチスレッド機能やメモリ保護機能をもつ。開発用言語は C++ や Java ME などである。Java と同様に、開発者がライセンス料を支払わずに、プログラムを開発することができる。
  • BREWの技術は、Qualcomm社が開発し推進している、携帯電話向けのプラットフォームである。開発用言語は C/C++ である。Javaと異なり、プログラムを開発するために、開発者がライセンス料を支払う必要がある。BREWプログラムは、携帯電話利用者に課金する機能にアクセスすることができる。この課金機能は、Qualcomm が管理する厳重な承認機能を、必要とする。この承認機能により、ライセンス料を徴収することができ、また携帯電話ごとにどの BREW プログラムが使えるかを制御することができる。BREWを採用する携帯電話事業社は、排他的なコンテンツ配布の技術を使うことができる。一部の携帯電話事業社はこのコンテンツ配布技術から利益を得ることができると考えている。

世界的な動向としては、

  • GSM の方式を採用するほとんどの携帯電話事業社は、Java を採用する傾向がある。
  • CDMA の方式を採用する携帯電話事業社の多くは、BREW を採用する傾向がある。ただし例外的に、CDMA 方式を採用するアメリカ合衆国の携帯電話事業者 Sprint Nextel Corporation は、Java を採用している。
  • Symbian のスマートフォンは、スマートフォン市場で 85% を占有している。
  • Javaの実装は携帯機器(携帯電話・PHSやPDA・スマートフォン等)に広く普及している。

また、2001年にはソニー社のコンシューマゲーム機 PlayStation2 にJava仮想マシンが搭載される予定と発表され話題になった。

バージョン履歴

Java は、JDK (Java Development Kit; Java開発キット) 1.0 以来、数度のメジャーバージョンアップを経ている。 バージョンアップに伴い、多くのクラスとパッケージが標準ライブラリに追加されてきた。 プログラミング言語JavaおよびJavaプラットフォームは、高い水準でバージョン間の互換性を保ちつつ発展してきている。

J2SE 1.4 から、Javaの開発は JCP (Java Community Process) という標準化プロセスで行うようになっている。 JCP では、JSRs (Java Specification Requests) という文書群により、Javaに対する追加機能やJavaプラットフォームに対する変更の提案と規定を行う。

言語仕様は JLS (Java Language Specification; Java言語仕様) により規定する。 JLS は JSR 901 の管理下にある。

  • JDK 1.0 (1996年1月23日) : 最初のバージョン。プレスリリース (英語)
    • このバージョンでは日本語などの国際化対応はなされていなかった。
  • JDK 1.1 (1997年2月19日) : いくつかの重要な機能が追加された。プレスリリース (英語)
    • 国際化対応 (日本語も含む)
    • AWT イベントモデルにおける大規模な再構成
    • 言語仕様に「内部クラス」が追加された
    • JavaBeans ソフトウェアコンポーネント技術
    • JDBC データベース接続API
    • Java RMI 分散オブジェクト技術
  • J2SE 1.2 (1998年12月8日) : コードネームPlayground。このバージョンから呼称が Java 2 に変更され (J2SE 5.0 までこの呼称が使われる) 、またエディション名が JDK から "J2SE" (Java 2 Platform, Standard Edition) に変更された。この J2SE の名称により、J2EE (Java 2 Platform, Enterprise Edition) および J2ME (Java 2 Platform, Micro Edition) の基となるエディションであることが明確化された。プレスリリース (英語)
    • strictfp キーワード : IEEE 754に基づいた厳密な浮動小数点数の演算を行う
    • リフレクション : クラス名やメソッド名を動的に指定して呼び出す (メソッドは、クラスに定義されている操作のこと)
    • Swing グラフィカルユーザインターフェースツールキットが標準ライブラリに統合された
    • サンのJava仮想マシンにジャストインタイムコンパイラが備わる
    • Java Plug-in : さまざまなウェブブラウザにJava実行環境を組み込むことができるようになり、Javaアプレットを実行できるようになった
    • Java IDL という IDL の実装が導入され、CORBA 分散オブジェクト環境との相互運用ができるようになった
    • コレクションフレームワークの導入
  • J2SE 1.3 (2000年5月8日) : コードネームKestrel。プレスリリース (英語) 新機能の概要 (日本語)
    • HotSpot Java仮想マシンが導入され、ジャストインタイムコンパイラに加えて動的再コンパイル技術、世代別ガベージコレクションを備えた高速なJava仮想マシンを使えるようになった。
    • Java RMI が CORBA ベースに変更される
    • JavaSound : 音声データを扱うAPI
    • Java Naming and Directory Interface (JNDI) が標準ライブラリに統合される (ネーミングサービスとディレクトリサービスへのアクセス。従来は拡張機能として提供されていた)
    • Java Platform Debugger Architecture (JPDA) の導入 (Javaプログラムのデバッグを支援する機能群)
  • J2SE 1.4 (2002年2月6日) : コードネームMerlin。このバージョンは、JCP (Java Community Process) のもとで開発された最初のJavaプラットフォームである (JSR 59)。プレスリリース (英語) 新機能の概要 (日本語)
    • assert キーワード : ある程度、「契約による設計」に基づいたプログラミングが可能となる。(JSR 41 で規定された)
    • Perlのような正規表現のライブラリの導入により、文字列データ (テキスト) の高度な処理機能が提供される
    • 連鎖例外機能により、ある例外の原因となった例外を連鎖的に記録できるようになる
    • NIO (New I/O) : 新しい入出力機能。(JSR 51で規定)
    • ロギング API が標準ライブラリに追加される (JSR 47で規定)
    • イメージ I/O API : JPEG や PNG のようなフォーマットの画像 (イメージ) を読み書きするAPI
    • JAXP (Java API for XML Processing) による統合された XML プロセサと XSLT プロセサによるXML文書処理機能のライブラリが、標準で提供されるようになった。 (JSR 5およびJSR 63で規定)
    • セキュリティと暗号化の拡張機能を標準ライブラリに統合
      • JCE (Java Cryptography Extension) : Java暗号化拡張機能
      • JSSE (Java Secure Socket Extension) : Javaでセキュアなインターネット通信 (TLS/SSL) を実現する機能
      • JAAS (Java Authentication and Authorization Service) : Javaの認証と権限のサービス
    • Java Web Start の導入 : Javaアプリケーションの配備と実行を簡素化する技術。(JSR 56で規定)
  • J2SE 5.0 (2004年9月30日) : コードネームTiger。JSR 176 のもとで開発された。J2SE 5.0 では、言語仕様に大きく拡張が加えられ、多くの新しい言語機能が追加された。プレスリリース (英語) 新機能の概要 (日本語)
    • 総称型 : コンパイル時に (静的に) コレクションオブジェクトでその要素となるオブジェクトの型を安全に取り扱うことができるようになった。ほとんどの場合において型変換 (キャスト) を行う必要は無くなった。(JSR 14で規定された)
    • オートボクシング/アンボクシング : int型のような基本型 (primitive type) とIntegerクラスのようなラッパクラスの間の変換が自動的に行われるようになった。(JSR 201で規定)
    • 列挙型 : enumキーワードにより、タイプセーフenumパターンが言語レベルでサポートされ、列挙型 (順序つきリストの値、多くの場合は定数) を安全に定義することができる (例: Day.MONDAYDay.TUESDAY など)。以前のバージョンまではこのような場合、タイプセーフではない整数の定数値で定義するか、プログラマが自分でタイプセーフenumパターンで実装するかの、どちらかの方法しか無かった。(JSR 201で規定)
    • 可変引数 : メソッドの最後の引数を、型名に続けて3個のドットを記述することができるようになった (例: void drawText(String... lines) ) 。メソッド呼び出しにおいて、最後の引数に関してはその型の任意の個数のパラメタを渡すことができる。その際、実際には内部的に最後の引数は配列としてメソッドに渡される。
    • メタデータ : 注釈 (アノテーション) ともいい、クラスやメソッドに、"@" でタグ付けされた付加的な情報 (メタデータ) を記述することができるようになる。メタデータを扱うツールで処理することにより、決まった型のコードを生成することができるようになり、Javaによる開発で機械的な作業を減らして開発効率を上げることができる。 (JSR 175で規定)
    • 拡張forループ (for-each文) : for文によるループの構文が拡張された。配列やコレクションオブジェクト (ListSetなど) の各要素オブジェクトに対して、反復 (繰り返し) 処理をする専用の構文を使うことで、コーディングを簡略化しミスを減らすことができるようになった。この構文を使う場合、コレクションは、配列であるかIterableインタフェースを実装したコレクションオブジェクトである必要がある。この構文を使ったコーディング例を示す。
void displayWidgets (Iterable<Widget> widgets) {
    for (Widget w : widgets) {
        w.display();
    }
}

この例では、widgets という変数名のコレクションオブジェクト内の、各Widgetオブジェクトを反復して繰り返し処理する。各Widgetオブジェクトにはループサイクルごとに w という変数名をつける。各ループサイクルで、w に対してWidget型で定義されているdisplay()メソッドを呼び出す。(拡張forループはJSR 201で規定された) |}

  • Java SE 6 (2006年12月11日) : コードネームMustang。JSR 270のもとで開発された。Java SE 6 においては、サンは命名方針を変更して、"J2SE" から Java SE に変更し、バージョン番号から ".0" の部分を廃止している。
    • Scripting for the Java Platform
    • AWT、Swing の高速化。
    • Windowsシステムトレイのサポート
    • Avalon (Windows Vista) のルックアンドフィール
    • テキストの正規化(java.text.Normalizer)
    • JDBC 4.0
    • JAXP (Java API for XML Processing) 1.4
    • Webサービス
  • Java SE 7 : コードネーム Dolphin。2006年の時点では、このバージョンの開発は計画の初期段階である。2006年から開発開始され、2008年にリリースされる見通しである。

バージョンアップの過程で、言語仕様の変更だけでなく、標準クラスライブラリにおいても大きな変更が加えられている。 JDK 1.0 では標準ライブラリは約200クラス/インタフェースであったが、Java SE 6 では4000以上のクラス/インタフェースとなっている。 Swing や Java 2D のような全く新しいAPIが追加された。 その一方で、もともと JDK 1.0 から存在していたクラスのメソッドの多くが、J2SE 5.0 での使用は推奨されないようになっている。

特徴

Javaの主な特徴を述べる。

思想

Javaを開発する上では、5つの目標があった。

  • オブジェクト指向プログラミングの方法論を採用する
  • 異なるオペレーティングシステム上で同一のプログラムが動くようにする
  • コンピュータ・ネットワークを扱う機能を標準で備える
  • 遠隔のコンピュータ上にある実行コードを安全に実行できるよう設計する
  • 開発をしやすくするために、従来の C++ などのオブジェクト指向プログラミング言語から良い部分を引き継ぐ

ネットワーク機能および遠隔コンピュータの実行コードの実行を実現するために、場合によっては、Javaプログラマは、CORBA や Internet Communications Engine、OSGi のような拡張機能を使う。

オブジェクト指向プログラミング

Javaはクラスベースのオブジェクト指向プログラミング言語である。 Javaのプログラムは複数のクラスから構成され、プログラムの実行は、各クラスが実体化したオブジェクト群が相互にメッセージをやりとりしながら行われる。 Javaでは、実装の単一継承を採用し、一つのクラスが複数のインタフェースをもつことができる。 クラスとは、オブジェクト指向においてオブジェクトの設計図にあたるものである。 オブジェクトについては後述する。 継承とは、既存のクラスを基にして、そのクラスの機能を引き継いだ新しいクラスを定義できることをいう。 Javaでは実装の多重継承は採用していない。 Javaでは一つのクラスが複数のインタフェースをもてるため、一つのクラスに複数の役割をもたせることができる。

Javaで扱うデータ/オブジェクトの型 (データ型) は、強い静的型付けを採用している。 静的型付けにより、Javaのコンパイラおよび実行環境が、型同士の整合性を検査することによって、プログラムが正しく記述されていることや、安全に動作することの検証が、可能である。

Javaのデータ型には、参照型 (reference type) と基本型 (プリミティブ型、primitive type) の2種類がある。 Javaのオブジェクトは全て参照型である。 Javaの基本型は、単純な構造のデータ (数値、論理値、文字 など) のための型である。 Javaの標準ライブラリは、基本型の値をオブジェクトとして扱えるようにするためのクラス (ラッパクラス) を提供している。 近年のJava (J2SE 5.0) からは型の扱いに改良が加えられている。

  • Javaのコンパイラが自動的に基本型のデータとそれに対応する参照型のラッパオブジェクトとの間の変換を行う (オートボクシング/アンボクシング) 。これにより、Javaで参照型と基本型の2種類のデータが存在することによる複雑さは、軽減されている。
  • 総称型を使えるようになった。プログラムにおける型変換 (キャスト) を減らすことができ、安全性が向上した。総称型は従来の C++ などの言語で実現されていた技術である。

Javaの特徴の一つであるオブジェクト指向プログラミングは、プログラミングおよびプログラミング言語設計の手法をいう。 Javaはオブジェクト指向プログラミング言語である。 オブジェクト指向の概念に対しては、多くの解釈がなされてきた。 一般には、オブジェクト指向を特徴づける重要な考え方は、ソフトウェアで扱うさまざまな種類のデータについて、データとそのデータに関連する手続きを一体化するように、ソフトウェアを設計することである。 こうして、データとコード (手続き) は、オブジェクトと呼ばれる実体に一体化される。 オブジェクトとは、状態 (データ) と振る舞い (コード、手続き) がひとかたまりとなったものと、考えることができる。

Java では、オブジェクトの設計図であるクラスに定義する振る舞い (コード) を「メソッド」と呼び、状態 (データ) を「フィールド」 (インスタンス変数) と呼ぶ。

オブジェクト指向以前の技術での本質的な問題点は、プログラムにおいて、データと振る舞い (コード) が、分離されていたことである。

  • あるデータ構造を変更する場合、関連してそのデータを処理するコードを変更を行う必要があるという、面倒ことになる。
  • 逆にコードを変更する場合に、関連してそのコードで扱うデータ構造を変更しなければならない場合もあった。

オブジェクト指向に基づいて、これまで分離されていた状態 (データ) と振る舞い (コード) を、オブジェクトに一体化することは、ソフトウェアシステムの設計において堅牢な基盤となる。 オブジェクト指向を有効に活用することにより、大規模なソフトウェア開発プロジェクトを管理することの困難さが軽減され、ソフトウェアの品質が向上し、失敗するプロジェクトの数を減らすことができる。

オブジェクト指向のもう一つの目標は、汎用的なオブジェクトを開発することで、プロジェクトをまたがってソフトウェアをより再利用可能にしてゆくというものである。 例えば、汎用的な「顧客」オブジェクトは、別のプロジェクトにおいても、理論的にはほぼ同一の手続き群を備えるであろう。 大きな組織において、その組織の複数のプロジェクトが機能的に共通する基盤層をもつ場合は、なおさらソフトウェアの再利用が重要となる。 こうしたことから、ソフトウェアオブジェクトは、さまざまなシステムに組み込み可能であるように、汎用性を備えていることが望ましい。 こうすることで、ソフトウェア業界は、既存のしっかりテストされたオブジェクトコンポーネントを活用してプロジェクトを進めることができ、開発期間を大幅に短縮することができる。

一方で、ソフトウェアの再利用性を高めるということには、実践においては、2つの大きな困難を伴う。

  • 真に汎用的なオブジェクトを設計する技法は簡単なことではないため、開発者にはあまり理解されていない
  • プロジェクトでどのような再利用可能なオブジェクトが使えるようになっているかについて、多くの開発者に伝えることができる環境を整える必要がある

いくつかのオープンソースコミュニティでは、再利用に伴う問題を軽減するために、オブジェクトやクラスライブラリの開発者に、自分たちが開発した汎用的で再利用可能な開発物についての情報を広報する手段を提供している。

プラットフォーム非依存

Javaのもう一つの特徴はプラットフォームに依存していないことであり、これは、Javaのプログラムがさまざまなハードウェアやオペレーティングシステム上で必ず同じように動くということを、意味する。 一度Javaのプログラムを作成すれば、そのプログラムはどのプラットフォーム上でも動くのである。 近年では、Java実行環境を構成するJava仮想マシンに高速化の技術が導入され、プラットフォームに依存したプログラムと同水準の実行性能を実現している。

Javaのプラットフォーム非依存は、次のようにして実現されている。

  • ほとんどのJavaのコンパイラ (Javaコンパイラ) は、Javaのソースコードを中間言語にコンパイルする。このJavaの中間言語のコードをバイトコードという。バイトコードはJava仮想マシン (Java VM、仮想マシンの一種) で実行可能な簡潔な機械語命令からなる。
  • Javaプログラムを実行する際には、このバイトコードをJava仮想マシン上で実行する。Java仮想マシンは、実行するハードウェアにネイティブなソフトウェアであり、中間言語であるバイトコードを解釈して実行する。
  • Java実行環境は、Java仮想マシンの他に、標準ライブラリを備えている。この標準ライブラリを利用することにより、Javaプログラムは、実行するマシンのさまざまな機能 (グラフィクス、スレッド、ネットワーク など) を、プラットフォームに依存しない単一の方法で使うことができるようになる。プラットフォームごとに異なる方法を使い分ける必要は無い。
  • 注意: Javaのバイトコードの実行時には、Java仮想マシンにより、最終的にはハードウェアにネイティブな機械語コードに変換されて実行される。このバイトコードから機械語コードへの変換は、
    • Java仮想マシンがインタプリタとして行う場合と、
    • Java仮想マシンがジャストインタイムコンパイラを使って行う場合とがある。

また、実際にはJavaコンパイラの実装として、ソースコードから直接にプラットフォームのハードウェアにネイティブなオブジェクトコード(機械語コード) を生成するものがある。 このようなJavaコンパイラの実装としては GNU の GCJ などがある。 この場合、中間言語のバイトコードを生成するという段階は省かれる。 しかしこの方法で生成されるJavaの実行コードは、コンパイル時に指定したプラットフォームでしか動かない。

Javaの実行コード (バイトコード) を生成する手段としては、プログラミング言語Javaでプログラムを書くことが標準的なやり方である。 Javaのバイトコードの実行は、Java仮想マシンという仮想マシンの環境上で行われる。 Java仮想マシンは実行時にバイトコードをネイティブコードに変換する。 なお、Javaのバイトコードを生成する他の方法としては、Ruby (JRuby) や Groovy 、Python (Jython) などのプログラミング言語でプログラムを書くこともできる。

サン・マイクロシステムズのJavaのライセンスは、全てのJava実行環境の実装は「互換性」を備えるべきであることを要求する。

最初期のJava実行環境の実装では、Javaプログラムの実行速度が遅かったが、近年では大きく改善されて、高速に実行できるようになった。 最初期のJava実行環境のJava仮想マシンの実装は、移植性を実現するためにインタプリタとして動作する仮想マシンを採用した。 こうした初期のJava実行環境の実装では、Javaプログラムの実行速度が C や C++ のプログラムと比べて遅かった。 そのため、Javaプログラムの実行速度は遅いという評判が広まった。 近年のJava実行環境の実装では、いくつかの技術を導入することにより、以前と比べて、Javaプログラムをかなり高速に実行できるようになった。

Javaプログラムを高速に実行するために使われる技術を説明する。

  • Java仮想マシンに高速化の技術を導入する。
    • Java仮想マシンにジャストインタイムコンパイル方式 (JITコンパイル方式) を導入する。ジャストインタイムコンパイラは、Javaプログラム (バイトコード) の実行時に、バイトコードをネイティブコードに変換する。
    • さらに洗練されたJava仮想マシンでは「動的再コンパイル」(dynamic recompilation) を行う。こうしたJava仮想マシンでは、実行中のプログラムを分析して、プログラムの重要な部分を特定して再コンパイルを行い最適化する。動的再コンパイルは、静的コンパイルよりも優れた最適化を行うことができる。その理由は、動的再コンパイルは、実行環境と実行中にロードされているクラスに関する情報に基づいて最適化しているからである。
    • Java仮想マシンに世代別ガーベジコレクションの技術を導入して自動ガーベジコレクション (後述) を効率化する。
  • あるいは、先に述べたように、Javaのソースコードを、従来の言語のコンパイラと同様に、単純にネイティブな機械語コードにコンパイルする。この場合、バイトコードを生成する過程は全く省かれる。この技術を使うと、良好な実行速度を得ることができる。ただし移植性 (プラットフォーム非依存) は損なわれる。

Java仮想マシンにジャストインタイムコンパイルと動的再コンパイル、世代別ガーベジコレクションの技術を導入することにより、Javaプログラムは、移植性を保ちつつ、ネイティブコードと同水準で高速に実行することができるようになった。

Javaの移植性 (プラットフォーム非依存) がどの程度実現できているかについては、議論の対象となっている。 技術的には移植性とは実現が難しい目標である。 多くのプラットフォームにおいて同一に動作するJavaプログラムを作成することは、可能である。 しかし実際には、Javaを利用できるプラットフォームによってはちょっとしたエラーが発生したり、微妙に異なる動作をする事例が多い。 こうしたことから一部の人々は、サン・マイクロシステムズのJavaの売り文句である "Write once, run anywhere" (一度コードを書けば、どの環境でも動く) をもじって "Write once, debug everywhere" (一度コードを書けば、どの環境でもデバッグが必要) と皮肉をいわれることがある。

しかしながら、Javaのプラットフォーム非依存は、サーバ側や組み込みシステムのアプリケーションに関しては、非常に成功している。 サーバ側 (Java EE) では、Javaの サーブレット、Webサービス、EJB (Enterprise JavaBeans) などの技術が広く使われている。 組み込みシステムの分野においても、組み込みシステム向けのJava環境 (Java ME) を使った OSGi を基にした開発が広く行われている。

自動ガーベジコレクション

Javaでは、自動ガーベジコレクションを備えており、この機能を備えていない従来の多くの言語と比べて、プログラムの開発生産性と安定性が高い。Javaの自動ガーベジコレクションにより、プログラマの負担は、完全に解消されるわけではないものの、大きく軽減される。近年のJavaの自動ガーベジコレクションでは世代別ガベージコレクションという効率的な技術を導入している。自動ガーベジコレクションを備えていない言語である C++の場合は、プログラマは自分自身でメモリ (主記憶装置) の管理をしなければならないという負担に苦しめられる。

Javaでは、自動ガーベジコレクションを備えていない言語における潜在的な問題は、自動ガーベジコレクション機能によって、その多くを未然に防ぐことができる。 プログラマは任意の時点でオブジェクトを生成することができ、Java実行環境は生成されたオブジェクトのライフサイクルを管理する責任をもつ。

プログラム (オブジェクト) は、他のオブジェクトへの参照をもち、そのオブジェクトのメソッド (手続き) を呼び出すことができる。 他のオブジェクトへの参照とは、低水準の視点で述べると、メモリ (主記憶装置) 内のヒープという領域上に確保されたそのオブジェクトを指すアドレスのことである。

オブジェクトがどこからも参照されなくなった場合、Javaのガーベジコレクション機能が自動的にその「到達不可能なオブジェクト」を削除し、そのメモリ領域を開放することで、メモリリーク (解放し忘れた未解放メモリが累積していき利用できるメモリの量が減ってゆく問題) を防ぐ。

ただしJavaの自動ガーベジコレクション機能は、メモリリークの問題を完全に解消するわけではない。 プログラマが、自分のプログラムでもはや必要のないオブジェクトへの参照を保持し続けた場合は、やはりメモリリークが発生する可能性がある。

別の表現で述べると、Javaでは、メモリリークは概念的に高い水準においては、発生する可能性が残っているということである。 概念的に低い水準においては、正しく実装されたJava仮想マシンを使えば、メモリリークが発生する可能性は無くなった。 全体として、Javaの自動ガーベジコレクション機能により、C++の場合と比べると、オブジェクトの生成と削除は、より簡潔になり、潜在的に安全になり、また多くの場合は高速になっている。

C++においても、しようと思えば、Javaと同等のメモリ管理の高速性と効率性を実現することはできるが、先に述べたとおり、複雑な作業で間違えやすく、完璧に行おうとすれば開発期間が非常に長くなり、開発したソフトウェアはかなり複雑で難解になる。 例えば、C++で特定のクラスを対象として、高速実行およびメモリ利用の断片化の最小化を、高水準で達成できるメモリ管理モデルで設計開発する技法があるが、こうした技法は複雑である。

自動ガーベジコレクションの機構は、Java仮想マシンに組み込まれており、開発者からは、事実上隠蔽されている。 開発者は、場合にもよるが、ガーベジコレクションがいつ起こるか意識しなくて良い。 というのも多くの場合、ガーベジコレクションの実行は、プログラマが自分で書いたコードによって明示的に起こる何らかの挙動と、必ずしも関連しているわけではないからである。

ネットワーク機能

Javaでは充実したライブラリにより、コンピュータ・ネットワークを使うソフトウェアを、効率良く開発することができる。 Javaの初期のバージョンから、TCP/IP (IPv4) のライブラリを備えており、ネットワークでソケット通信を行うソフトウェアを簡単に実装することができた。 分散オブジェクト環境のソフトウェアの開発も早い時期からできるようになった。 Java RMI もしくは CORBA の分散オブジェクト技術を標準で使うことができる。 近年では、標準、拡張その他のライブラリにより、さまざまなネットワークプロトコルを高水準で扱えるようになっている。

  • FTP (ファイル送受信)
  • HTTP (ウェブによるデータ送受信)
  • SMTP/POP/IMAP、NNTP (電子メール送受信、ネットニュース)
  • SSH、TLS/SSL (セキュアな通信により盗聴やなりすましを防ぐ)
  • SMB (ファイルサーバへのアクセス)
  • ほか

現在では IPv6 も扱えるようになりつつある。

XML 文書を扱う技術とネットワーク機能を有効に組み合わせることにより、高度なシステムやサービスを構築できるようになっている。

セキュリティ

Javaでは初期のバージョンから遠隔のコンピュータ上にある実行コード (Javaアプレット) を安全に実行できるよう設計されていた。

  • Java仮想マシンのバイトコード検証機能により、Javaの実行コードであるバイトコードの文法などが正しいかどうかを検査する。
  • Java実行環境のクラスローダ機能により、クラス (バイトコード) をロードする際にそのクラスの情報を調べて、安全性を検査する。
  • Java実行環境のセキュリティマネージャ機能 (サンドボックス) により、Javaアプレットが、ユーザによって許可された資源以外の資源に不正にアクセスすることを防ぐ。
    • Java実行環境の既定の設定では、遠隔のコンピュータ上にある実行コード (Javaアプレット) に対して、ローカルにあるファイル等へのアクセスや、アプレットのダウンロード元以外の遠隔コンピュータとの通信を、禁止している。

名前空間

Javaは、パッケージという名前空間の機構をもつ言語であり、ライブラリおよびアプリケーションソフトウェアに含まれる多数のJavaのプログラム (クラスとインタフェース) を、パッケージの階層構造に分類・整理することができる。 名前空間の機構をもたない言語と比べて、多数のクラスとインタフェースの管理が容易となり、クラスとインタフェースの命名についても、既存のものとの名前の衝突回避を考慮する労力が、大きく軽減される。

実行形態

Javaのバイトコードには複数の実行形態があると考えることができる。 ただしいずれのバイトコードも、Java実行環境 (JRE) のもとで実行されるという点では、同じと考えることもできる。

Javaアプリケーション
ローカルのコンピュータで実行されるJavaプログラム。
Javaアプレット
ネットワーク上に置かれウェブブラウザ上で実行できるJavaプログラム。ワンクリックで実行できるため、その動作にはサンドボックス機構のもとで厳しい制限が加えられている。
Javaサーブレット
Webページを動的に作るJavaプログラム。PerlなどによるCGIに比べ、サーバー負荷が低いなどのメリットがある。
JavaServer Pages (JSP)
XHTML(HTML) 内に記述するJavaプログラム。サーバー側で解釈して動的にWebページを作り出す。コードの見た目は似ているが、ECMAScript(JavaScript) のようにブラウザ側で実行するスクリプトではない。サーブレットの機能を補完するもの。類似の技術に Active Server Pages (ASP) 、ASP.NET、PHP などがある。
Java Web Start
Javaアプリケーションを簡単に配備し実行する仕組み。拡張子がjnlpとなっているファイルをウェブブラウザなどでワンクリックしただけで自動ダウンロード、自動インストール、最新バージョンがあるかをネット上で自動チェックしあれば自動アップデートしてから実行する。Javaアプレットのように実行時にブラウザを必要とすることはない。類似技術としてマイクロソフトのノータッチデプロイメント、ClickOnce がある。

文法

プログラミング言語Javaの文法は、C および C++ から多くを引き継いでいる。 このためJavaの文法は、多くのプログラマにとって習得しやすくなっている。 Javaが世に現れる以前は、Cのプログラマが多く、またオブジェクト指向プログラミング言語の中では、C++は広く使われてきた言語の一つであった。 しかし Java では、C++ とは違って、言語の基礎的な部分から全体にわたって、オブジェクト指向プログラミングの思想が貫かれている。 C++ の文法は、構造化プログラミング、総称的プログラミング (generic programing) 、およびオブジェクト指向プログラミングの構文が集まってハイブリッドに構成されている。 Javaでは、若干の例外を除き、全てがオブジェクトであり、全てはクラス内に記述する。

Hello world

次の節以降では、Hello world プログラムで、Javaプログラムの例を示して説明する。

Hello world プログラムとは、"Hello, world" という文字列をディスプレイなどの出力装置に出力する簡単なソフトウェアプログラムである。プログラミング言語の初学者向けのプログラム例としてよく使われる。

なお先に述べたとおり、Javaには複数の実行形態があると考えることができるので、以降では、それぞれの実行形態における Hello world プログラムを例示する。

例: スタンドアロン (コマンドライン)

コマンドライン環境で動くスタンドアロンのJavaアプリケーションの例を示す。 Javaでは、他のプログラミング言語と同様に、コマンドライン環境で動くプログラムを簡単に開発できる。

// Hello.java
public class Hello {
    public static void main(String[] args) {
        System.out.println("Hello, world!"); 
    }  
}

このプログラムについて説明する。

  • Java のプログラムでは全てを class 内に記述する。コマンドラインのスタンドアロンアプリケーションの場合も同じである。
  • ソースコードのファイル名は、そのファイルで記述しているクラスの名前に ".java" というサフィクス (接尾辞、拡張子) をつけるという規則で、命名する。
    このプログラム例では、クラス名は Hello であるため、"Hello.java" というソースファイル名にする必要がある。
  • コンパイラは、ソースファイルで定義されている各クラスのクラスファイル (バイトコード) を生成する。クラスファイルの名称は、そのクラスの名前に ".class" のサフィクスをつけた名前になる。
    • クラスファイルの生成において、内部クラスの一種である無名クラス (anonymous class) の場合は、クラスファイルの名称は、その無名クラスを含むクラスの名称と整数 (0から始まり、無名クラスが複数ある場合は、さらに1、2...と順に付番される) を "$" で連結した文字列に、通常のクラスと同じく ".class" のサフィクスをつけた名前になる。
  • この例のように、スタンドアロンで実行するプログラム (クラス) では main() メソッドを定義する必要がある。メソッド定義には振る舞いを記述する。この main メソッドのシグニチャ (戻り値、引数) は次のようにしなければならない。
    • 戻り値の指定には void キーワードを使う。void は、そのメソッドが何も戻り値を返さないことを示す。
    • main メソッドは、パラメタ (引数) として1つのStringの配列を受け取らなくてはならない。このString配列の引数の名称は args とすることが慣習となっている。ただし引数として可能な名称であれば他の名称でも構わない。
    • main メソッドには static キーワードをつけなければならない。static は、そのメソッドがクラスメソッドであることを示す。クラスメソッドは、クラスと関連するメソッドであり、オブジェクトインスタンスに関連するメソッド (インスタンスメソッド) ではない。
    • main メソッドは public キーワードをつけて宣言する。public は、そのメソッドが他のクラスのコードから呼び出せること、およびそのクラスが他のクラスから呼び出される可能性があることを、示す。ここでの「他のクラス」とは、そのクラスの継承階層に関係なく、他の全てのクラスを意味する。
  • 印字出力機能は、Javaの標準ライブラリに含まれている。System クラスは public static のフィールド out をもつ。out オブジェクトは、PrintStream クラスのインスタンスであり、標準出力ストリームを表す。PrintStreamクラスのインスタンスである out オブジェクトは、println(String) メソッドをもつ。このメソッドはデータをストリームに出力する。ストリームとは入出力を抽象化した概念である。この場合は、データを画面 (out 、標準出力) に出力する。
  • スタンドアロンプログラムを実行するには、Java実行環境に呼び出す対象となる main メソッドをもつクラスの名前を渡すことによって、Java実行環境に実行を指示する。 UNIX 環境の場合は、カレントディレクトリから java -cp . Hello をコマンドラインで入力することで、この例のプログラム (Hello.class にコンパイルされたクラス) を実行することができる。
    • 実行する main メソッドをもつクラス名の指定については、Javaアーカイブ (Jar) ファイルの MANIFEST に記述する方法もある。

例: スタンドアロン (Swing)

グラフィカルユーザインタフェース (GUI) 環境で動く Swing を使ったスタンドアロンのJavaアプリケーションの例を示す。 Swing は、Java SE の高度な GUI のウィジェット・ツールキットのライブラリである。

// Hello.java
import javax.swing.*;
 
public class Hello extends JFrame {
    Hello() {
        setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
        add(new JLabel("Hello, world!"));
        pack();
    }
 
    public static void main(String[] args) {
        new Hello().setVisible(true);
    }
}
  • import 文は、コンパイル時にJavaコンパイラに対し、このソースコード内では javax.swing パッケージ内の全ての public なクラスとインタフェースを、パッケージ名をつけないでクラス名/インタフェース名だけで使うことを、伝える。
    import 文を記述しなくても、javax.swing.JFrame のようにパッケージ名をつけて完全修飾クラス名 (FQCN; Fully Qualified Class Name) で使うこともできるが、この例のように import 文を使うことで、単に JFrame のようにクラス名だけで使うことができるようになる。
  • Hello class extends JFrame の部分では、JFrame クラスを継承して Hello クラスを定義すること (JFrame のサブクラスとすること) を記述している。JFrame クラスは、ウィンドウ終了ボタンをもつタイトルバーの付いたウィンドウ (フレーム) を実装している。
  • Hello() コンストラクタでは、フレームを初期化している。
    • コンストラクタとは、特殊なメソッドであり、オブジェクトの状態を初期化する処理を記述する。オブジェクトが生成される際に自動的に呼び出される。この例では、main メソッドで Hello オブジェクト (フレーム) を生成する時に呼び出され、Hello オブジェクト (フレーム) の状態を初期化する役割を担っている。なお Java のコンストラクタには、クラス名と同じ名称をつける。
      • オブジェクトの初期化処理が必要無い場合などには、コンストラクタの明示的な定義を省略して良い。
    • このコンストラクタではまず、JFrame から継承された setDefaultCloseOperation(int) メソッドを呼び出し、タイトルバーのウィンドウ終了ボタンが押された際の既定の挙動を WindowConstants.DISPOSE_ON_CLOSE に設定する。これにより、ウィンドウ終了ボタンが押された際に、フレームが (単に不可視になるだけでなく) 破棄されることになり、Java仮想マシンが終了しプログラムが終了するようになる。
    • 次に、new JLabel"Hello, world!" の文字列表示のためにラベルオブジェクトを生成して、フレーム (JFrame) の継承元クラス Container から継承された add(Component) メソッドを、このラベルを引数として呼び出して、ラベルをフレーム上に追加配置する。
    • 継承元クラス Window から継承された pack() メソッドを呼び出して、フレームの大きさを調整し、フレーム内のコンポーネント (ラベル) の配置を調整する。
  • このプログラムが起動される時に、Java仮想マシンは main() メソッドを呼び出す。
    • main メソッドは new Hello() の部分でフレームのオブジェクトを生成する。このオブジェクト生成の際に、先に述べた Hello() コンストラクタの一連の処理が実行される。
    • 次に生成したオブジェクトに対して、その継承元クラス Component から継承された setVisible(boolean) メソッドを、boolean型のパラメタ true を引数として呼び出して、フレームを可視化する。
  • 注意: フレームが一度表示されたら、main メソッドが終了してもプログラムは終了しない。その理由は、AWT のイベントディスパッチングスレッドが終了するのは、全てのトップレベルの Swing ウィンドウが破棄された後であるためである。

例: アプレット

Javaアプレットは、他のアプリケーションに埋め込まれるプログラムである。 多くの場合は、ウェブブラウザに表示されるウェブページに埋め込まれる。

// Hello.java
import java.applet.Applet;
import java.awt.Graphics;
 
public class Hello extends Applet {
    public void paint(Graphics gc) {
        gc.drawString("Hello, world!", 65, 95);
    }    
}
<!-- Hello.html -->
<html>
  <head>
    <title>Hello World Applet</title>
  </head>
  <body>
    <div>
      <applet code="Hello" width="200" height="200">
      </applet>
    </div>
  </body>
</html>
  • import 文は、コンパイル時にJavaコンパイラに対し、このソースコード内では java.applet.Applet クラスと java.awt.Graphics クラスを、パッケージ名をつけないでクラス名だけで使うことを、伝える。
  • Hello class extends Applet の部分は、Hello クラス が Applet クラスを継承すること (Hello クラスが Applet クラスのサブクラスであること) を記述している。
  • Applet クラスは、ホストアプリケーション (アプレットを実行するアプリケーション) 上で、アプレットによるグラフィクスの表示やアプレットのライフサイクル制御を支援するフレームワークを提供する。
    • Applet は抽象ウィンドウツールキット (AWT; Abstract Window Toolkit) の Component である。Component (を継承したクラス) であるため、Applet は、グラフィカルユーザインターフェース (GUI) を備えており、開発者はイベント駆動プログラミングの作法でアプレットを開発することができる。
  • Hello クラスは Container スーパークラスから継承された paint(Graphics) メソッドをオーバーライドしている。
    • オーバーライドとは、スーパークラスで定義された、既定の振る舞いを実装したメソッドや抽象メソッドを、サブクラス側で実装し直すことをいう。
  • この paint(Graphics) メソッドのオーバーライドにより、Hello アプレットを表示する処理を実装することができる。paint(Graphics) メソッドは、アプレットに Graphics オブジェクトを渡す (アプレットは Graphics オブジェクトを受け取る) 。Graphics オブジェクトは、アプレットを表示するために使われるグラフィクスコンテクストを表している。
  • この例では、Graphics オブジェクト (グラフィクスコンテクスト) の drawString(String, int, int) メソッドを呼び出して、アプレット表示域の (65, 95) ピクセル座標 (オフセット) で "Hello, world!" 文字列を表示する。
  • この例では、アプレットは XHTML(HTML) 文書内の、applet 要素 (<applet> タグ) が使われている位置に表示される。applet 要素は、3つの属性をもつ。
    • code="Hello" は、Applet クラスの名前を示す。
    • width="200" height="200" は、アプレット領域の幅 (width) と高さ (height) を設定する。
  • 注意: アプレットは、applet 要素の代わりに、object 要素あるいは embed 要素を使っても XHTML 文書に埋め込むことができる。ただし現時点では、ウェブブラウザによるこの2つの要素の扱いは、ブラウザごとに異なることがある。 XHTML 1.1 仕様においては applet 要素は廃止され、アプレットを使う場合は object 要素を使うことになる。

例: サーブレット

Javaサーブレットは、サーバ側の Java EE の構成要素であり、クライアントから受けた要求 (request) に対する応答 (response) を生成する。 現在、多くの場合はウェブブラウザから要求を受け、応答としてXHTML/HTMLのウェブページを動的に生成する。

// Hello.java
import java.io.*;
import javax.servlet.*;
 
public class Hello extends GenericServlet {
    public void service(ServletRequest request, ServletResponse response)
        throws ServletException, IOException {
        response.setContentType("text/html");
        PrintWriter pw = response.getWriter();
        pw.println("Hello, world!");
    }
}
  • import 文は、コンパイル時にJavaコンパイラに対し、このソースコード内では java.io パッケージおよび javax.servlet パッケージ内の全ての public なクラスとインタフェースを、パッケージ名をつけないでクラス名/インタフェース名だけで使うことを、伝える。
  • Hello class extends GenericServlet の部分は、Hello クラス が GenericServlet クラスを継承すること (GenericServlet のサブクラスであること) を記述している。
  • GenericServlet クラスは、サーブレットの一般的なフレームワークを提供する。サーバ上で、クライアントから送られてきた要求をサーブレットに渡し、サーブレットのライフサイクルを制御する。
  • Hello クラスは Servlet で宣言された service(ServletRequest, ServletResponse) メソッドをオーバーライドしている。このメソッドは、クライアントからの要求を扱うコードを開発者が記述する場所として、サーブレットフレームワークが開発者に提供しているメソッドである。service(ServletRequest, ServletResponse) メソッドは、 ServletRequest オブジェクトと ServletResponse オブジェクトを Hello に渡す (HelloServletRequestServletResponse を受け取る) 。
    • ServletRequest オブジェクトは、クライアントから送られてきた要求を表すオブジェクトである。
    • ServletResponse オブジェクトは、クライアントに送り返す応答を表すオブジェクトである。
  • service(ServletRequest, ServletResponse) メソッドの throws ServletException, IOException の部分では、このメソッドが ServletException もしくは IOException の例外を投げる可能性があることを宣言している。これらの例外は、Hello サーブレットの実行中に何らかの問題が起こり、クライアントからの要求に正常な応答を返すことができなくなった場合に投げられる。
  • setContentType(String) メソッドを呼び出して、クライアントに返すデータの MIME Content-Type を "text/html" に設定する。
  • getWriter() メソッドを呼び出して PrintWriter オブジェクトを取得する。このオブジェクトを使ってクライアントに返すデータを書き出す (出力する) ことができる。
  • println(String) メソッドを呼び出して、"Hello, world!" 文字列を応答データとして書き出す。
  • そして応答データはソケットストリームに書き出され、クライアントに返される。

構成

Javaプラットフォームの構成を説明する。

  • #Java実行環境 (JRE) は、Javaプラットフォームに配置されたJavaアプリケーションを実行するために必要な、ソフトウェアである。標準クラスライブラリやJava仮想マシンなどから構成される。
  • #Java開発キット (JDK) は、Javaプログラムの開発を支援する基本的なソフトウェアである。
  • #JREとJDKの複数の実装で、JREとJDKの開発と提供の状況について簡単に述べる。
  • #Javaのエディションで、サン・マイクロシステムズとJCPが規定している3つのJavaのエディションについて簡単に述べる。
  • #拡張機能と関連技術で、Javaの主な拡張機能と関連する技術を述べる。

Java実行環境

Java実行環境 (JRE; Java Runtime Environment) は、Javaプラットフォームに配置されたJavaアプリケーションを実行するために必要な、ソフトウェアである。 標準クラスライブラリやJava仮想マシンなどから構成される。 エンドユーザは普通、Javaソフトウェアパッケージやウェブブラウザプラグインの利用を通じて JRE を使う。 サン・マイクロシステムズ/JCP をはじめ複数の団体や企業により、 さまざまなプラットフォーム向けに、多くの JRE の実装が開発・提供されている。

JRE の他、サン/JCPなどの団体・企業は、Java開発キット (JDK) と呼ばれる JRE のスーパーセットの実装を開発・提供している。JDK は、Javaプログラムの開発を支援する基本的なソフトウェアであり、多くの開発ツールが含まれている。

実行環境の構成

Java実行環境は、標準クラスライブラリとJava仮想マシン、およびいくつかのファイルとソフトウェアから構成される。

  • Javaクラスライブラリ群 (標準クラスライブラリ)
    実行環境に含まれるJavaクラスライブラリ群 (標準クラスライブラリ) の実体は、JRE (Java実行環境) を実装した人々がJava標準クラスライブラリのソースコードからコンパイルしたバイトコードである。このライブラリ群はJavaアプリケーションを実行するために必要であり、またJavaアプリケーション開発者も標準クラスライブラリを使って開発する。この標準クラスライブラリには、以下のライブラリが含まれる。
    • コアライブラリ
      • コレクションのライブラリ
        リストや連想配列 (ハッシュテーブル)、木構造 (ツリー)、集合 (セット) などのデータ構造 (およびアルゴリズム) を実装している。
      • リフレクション : Javaでは実行時にもクラスやメソッドの情報をもっており、クラス名やメソッド名を動的に指定して呼び出すことができる。
      • XML文書を扱うライブラリ
      • セキュリティ機能
      • 国際化と地域化のライブラリ
      • シリアライズ (serialization、オブジェクト直列化) : オブジェクトの参照をたどって関連するオブジェクトをまとめてバイトストリームにすることができる。そのストリームをファイルに書き込めば、オブジェクトの状態をそのまま保存 (永続化) できる。
    • 統合ライブラリ (外部システムとの連携機能)
      • JDBC: データベース接続のAPI
      • JNDI (Java Naming and Directory Interface) : ネーミングサービス・ディレクトリサービスへのアクセス
      • Java RMI (Remote Method Invocation、遠隔メソッド呼び出し) と CORBA : 分散オブジェクト環境 (分散処理環境)
        • 分散システムなどで、別のJava仮想マシンにあるオブジェクトがお互いのメソッドを呼ぶことができる。ソケット等を直接利用する通信の低水準な実装をせずに、簡単に高水準な実装をすることができる。
    • グラフィカルユーザインターフェース (GUI) のライブラリ
      • AWT (Abstract Window Toolkit、抽象ウィンドウツールキット)
        重量コンポーネント (ネイティブコンポーネント) のライブラリ。重量コンポーネントを配置しイベント制御を行うことができる。
      • Swing
        軽量コンポーネントのライブラリ。AWT を使って開発されたが、ネイティブではないウィジェット (GUIの部品要素) の実装を提供する。
      • Java 2D : 2次元グラフィクスや画像 (JPEGなど) を扱うライブラリ。
      • Java Sound など音声を扱うAPI群 (録音、再生、その他の処理)
    • Javaアプレット
  • jar (Java Archive) : Javaプログラムの標準圧縮ファイルの圧縮・展開機能。拡張子の関連付けをすれば、jarファイルをダブルクリックすることで実行できる。実際はZIPで圧縮している。
  • JNI (Java Native Interface) : JavaからCなど他の言語で実装されたネイティブなプログラムやライブラリを呼び出すことができる。
  • Java仮想マシン (Java VM)
    仮想マシンの一種であり、プラットフォームに依存して実装された、JavaライブラリとJavaアプリケーションのバイトコードを実行するソフトウェア
  • プラグイン
    ウェブブラウザでJavaアプレットを実行するために必要なソフトウェア
  • Java Web Start
    Javaアプリケーションをウェブを介して効率的にエンドユーザに配布する機構
  • ライセンス文書および各種の文書

Java開発キット

Java開発キット (JDK; Java Development Kit) は、サン/JCP をはじめ複数の団体や企業により開発・提供されている、Javaプログラムの開発を支援する基本的なソフトウェアである。 Javaが世に出て以来、広く使われてきたJavaの開発ツールである。 Javaコンパイラ、javadoc、デバッガなどを含む多くの開発ツールが含まれている。 また、完全なJava実行環境 (JRE) を同梱している。

Javaプログラムを実行するだけであれば、Java開発キットを導入する必要は無い (Java実行環境が導入されていれば良い) 。

Java開発キット (JDK) の呼称は、これまでに何度か変更されている。

  • J2SE 1.2.2_004 までは JDK と呼んでいた。
  • J2SE 1.4 までは Java 2 SDK と呼んでいた。
  • J2SE 5.0 では 再び JDK と呼んでいる。

JREとJDKの複数の実装

広く使われているプラットフォームなどに対しては、複数の団体や企業が独自に JRE や JDK の実装を開発・提供している。 独自の最適化技術を適用したり、特定の用途に特化した最適化、あるいは異なるライセンスを採用するなど、それぞれ特徴がある。

  • Linux/IA-32プラットフォーム : サン、Blackdown、IBM、Kaffe.org、GNU、BEA などが JRE や JDK を実装・提供している。
  • Windows/IA-32プラットフォーム : サン、IBM、BEA などが JRE や JDK を実装・提供している。

オープンソース/フリーソフトウェアの実装

いくつかの団体が、オープンソースもしくはフリーソフトウェアのライセンスで利用できる、Java仮想マシンおよび JRE 、JDK の実装を開発している。 Java仮想マシンおよび標準ライブラリの仕様はサン/JCPが公開している。 サン/JCPのJava標準クラスライブラリのソースコードは JDK の一部として提供されているため、開発者はJava標準クラスライブラリのソースコードを参照することができる。 しかしサン/JCPのJava標準クラスライブラリのソースコードを改変することは、サンのライセンスにより認められていなかった (ただし2006年にサンはライセンスの方針を変更し近い将来オープンソースにする意向を表明している) 。 そのため一部の人々は、オープンソースもしくはフリーのライセンスで利用できる、サン/JCPとは別の、ただし互換性のあるJava標準クラスライブラリとJava仮想マシンを実装する作業を行っており、近い将来に完全な実装が完成し公開されるとみられる。

オープンソースもしくはフリーの実装を開発しているいくつかのプロジェクトを示す。

  • GNU Classpath - GNUプロジェクト
  • Kaffe - Kaffe.org
  • Apache Harmony - Apacheソフトウェア財団

GNU Classpath は、2007年3月現在、J2SE 1.4 のライブラリの 99% 以上を実装し、J2SE 5.0 では 95% 以上を実装している。 また Apache Harmony には IBM が協力している。

GCJ

GNUがGNUコンパイラコレクション (GCC) のJava版、GCJ (The GNU Compiler for the Java Programming Language) を出している。 ahead-of-time コンパイラを搭載しており、Javaのソースコードやバイトコードをネイティブマシンコード(Windowsの場合はexeファイル)に変換できる。 クラスライブラリは GNU Classpath を使っており、1.4のほとんどの部分が対応しており、5.0の部分も実装が進んでいる。

Windows環境では、GCJはMinGW (Minimalist GNU for Windows) もしくはCygwinを使って実行できる。 Cygwinの場合は、対象がライセンスがGPLのソフトウェアに限られるが、MinGWの場合は商用含め、全てのソフトウェアで利用できる。 GCC/GCJ for MinGWにて、MinGW版のGCJをまとめたパッケージが公開されている。

Excelsior JET

米Excelsior社が Excelsior JET というahead-of-timeコンパイラを販売している。Java SE 5.0 用に書かれたプログラムをWindowsのネイティブマシンコードであるexeファイル (実行ファイル) に変換できる。

Windows exeパッケージ化

Windowsにて、配布、実行しやすくするために、Javaのjarファイルをexeファイル (実行ファイル) でラッピングするツールがある。以下が、その一例である。

  • exewrap
  • JSmooth
  • Launch4j

Javaのエディション

サン・マイクロシステムズとJCP は、さまざまな環境に対応するため、3つのJavaプラットフォームのエディションを規定している。 Java の API の多くは分類され各エディションに割り当てられている。

エディションごとに実行環境と開発環境がある。 Java実行環境 (JRE) は、Java仮想マシンと標準ライブラリの実装から構成される。 JDK 1.1 のバージョンまでは、Java SE に相当するエディションのみが提供されていた。 3つのエディションが規定されたのは、JDK 1.1 の次のバージョンからである。 サン/JCP が規定しているエディションを次に示す。

Java SE
Java SE (Java Platform, Standard Edition) は、ワークステーション、パーソナルコンピュータ (PC) やサーバなどの機器で、汎用的な用途に使われる。
Java EE
Java EE (Java Platform, Enterprise Edition) は、Java SE に加え、多層クライアントサーバの大規模システムを開発するための、さまざまな API が追加されている。
Java ME
Java ME (Java Platform, Micro Edition) は、コンピュータ資源が限られている、組み込みシステムなどを用途として想定したエディションである。機器の種類に応じた、ライブラリのいくつかの異なるセット (プロファイル) を規定している。Java SE のいくつかのAPIは実装していないが、このエディションで対象とする用途には十分な機能をもっている。完全な Java SE のライブラリを使うには、このエディションで対象とする用途では記憶装置の容量が足りない。

Java API に含まれるクラスは、パッケージと呼ばれるグループに分類される (#名前空間) 。 各パッケージは、相互に関連するインタフェース、クラス、例外を含む。 Javaの各エディションでどのような機能が使えるかについては、それぞれのエディションの項目 (Java SE、Java EE、Java ME) を参照のこと。

JavaのAPIセットは、サン・マイクロシステムズと他の個人や企業・団体が共同で、JCP (Java Community Process) プログラムに沿って管理している。 このプロセスに参加する人々が、Java API の設計と開発に関わっている。 このプロセスのあり方については、議論の対象となっている。

2004年より、IBM と BEA は、Java の公式のオープンソース実装を作る動きを、公的に支援している。 2006年まで、サンはこうした動きに対しては拒否する立場をとってきたが、方針を変えて自社とJCPによるJavaの実装をオープンソースにする意向を表明し実行に移し始めている。

拡張機能と関連技術

Javaの標準機能に対する拡張機能は、多くの場合、javax.* パッケージに属する。 こうした拡張機能は、Java SE の Java開発キット (JDK) や Java実行環境 (JRE) には含まれない。 Javaの拡張機能や関連技術は、プログラミング言語Javaと密接に連携する。 主なJavaの拡張機能と関連技術を示す。(いくつかの拡張機能は近年の Java SE 標準ライブラリに統合された)

  • Java EE (従来のJ2EE) (Java Platform, Enterprise Edition) - 大規模で分散化された企業システムもしくはインターネットサーバ向けのJavaのエディション
  • Java ME (従来のJ2ME) (Java Platform, Micro Edition) - 携帯機器など資源が限られている環境向けのJavaのエディション
  • JMF (Java Media Framework) - 音声・動画などのマルチメディア向けのAPI
  • JNDI (Java Naming and Directory Interface) - ネーミングサービス・ディレクトリサービスへのアクセス
  • JSML (Java Speech Markup Language) - 音声合成システムにテキストの注釈を追加する
  • JDBC - データベース接続のAPI
  • JDO (Java Data Objects) - Javaオブジェクトの永続化のインタフェース
  • JAI (Java Advanced Imaging) - 画像を扱うための高水準なオブジェクト指向API
  • JAIN (Java API for Integrated Networks) - 統合された通信ネットワークのAPI
  • JDMK (Java Dynamic Management Kit) - JMX仕様 (後述) に基づいたアプリケーション開発を支援するソフトウェア
  • Jini - 分散システムを構築するネットワークアーキテクチャ
  • Jiro - 分散した記憶装置を管理する技術
  • Java Card - スマートカードなどの機器で安全にJavaアプリケーションの実行を実現する技術
  • JavaSpaces - 分散環境でJavaオブジェクトの送受信・永続化などを支援する技術
  • JML (Java Modeling Language) - 契約による設計 (Design by contract) に基づいた開発を支援する技術
  • JMI (Java Metadata Interface) - Javaのメタデータの作成・アクセス・検索・送受信に関する仕様
  • JMX (Java Management Extensions) - 分散環境における機器・アプリケーション・ネットワークサービスの管理/監視を行う技術
  • JSP (JavaServer Pages) - Java EE によるウェブアプリケーションで XHTML などのファイルにJavaのコードを埋め込み、動的に文書を生成する技術
  • JSF (JavaServer Faces) - Java EE によるウェブアプリケーションでユーザインタフェースの簡易な開発を支援する技術
  • JNI (Java Native Interface) - Javaから他の言語で実装されたネイティブなプログラムやライブラリを呼び出すための仕様
  • JXTA - Peer to Peer (P2P) の仮想ネットワークのためのオープンプロトコル
  • Java 3D - 3次元グラフィクスプログラミングのための高水準なAPI Java 3D
  • JOGL (Java OpenGL) - OpenGL を使う3Dグラフィクスプログラミングのための低水準なAPI
  • LWJGL (Light Weight Java Game Library) - ゲームを開発するための低水準なAPIで、OpenGL、OpenAL および多様な入力機器の制御機能も提供する
  • OSGi - サービスの動的な管理と遠隔保守
  • JavaDesktop

Java技術の標準化

現在、Javaプラットフォームの将来のバージョンや機能は、JCP (Java Community Process) の標準化プロセスのもとで開発されている。 JCP のメンバになることで、Java技術の将来のバージョンや機能の定義に関与することができる。 JCP には、さまざまな個人、団体、企業がメンバとして参加している (IBM、ボーランド、BEA Systems、富士通、Apacheソフトウェア財団、ヒューレット・パッカード など) 。

JCP は、Javaプラットフォームに追加する仕様や技術を、JSRs (Java Specification Requests) という文書群に記述する。

プログラミング言語JavaとJavaコアAPIに関わるいくつかの JSRs を示す。

  • JSR 14 Add Generic Types To The Java Programming Language (J2SE 5.0)
  • JSR 41 A Simple Assertion Facility (J2SE 1.4)
  • JSR 47 Logging API Specification (J2SE 1.4)
  • JSR 51 New I/O APIs for the Java Platform (J2SE 1.4)
  • JSR 59 J2SE Merlin Release Contents (J2SE 1.4)
  • JSR 121 Application Isolation API
  • JSR 133 Java Memory Model and Thread Specification Revision (J2SE 5.0)
  • JSR 166 Concurrency Utilities (J2SE 5.0)
  • JSR 175 A Metadata Facility for the Java Programming Language (J2SE 5.0)
  • JSR 176 J2SE 5.0 (Tiger) Release Contents (J2SE 5.0)
  • JSR 201 Extending the Java Programming Language with Enumerations, Autoboxing, Enhanced for loops and Static Import (J2SE 5.0)
  • JSR 203 More New I/O APIs for the Java Platform ("NIO.2") (Java SE 7)
  • JSR 204 Unicode Supplementary Character Support (J2SE 5.0) - Unicode 3.1 のサポート
  • JSR 244 Java EE 5 Specification (Java EE 5)
  • JSR 270 Java SE 6 ("Mustang") Release Contents (Java SE 6)
  • JSR 275 Physical Units/Quantities Support (Java SE) - JScience をもとにしたリファレンス実装
  • JSR 901 Java Language Specification (J2SE 5.0)

開発ツール

Javaアプリケーションを開発するための開発ツール (開発用ソフトウェア) をいくつか示す。 次に示すツール以外にも、数多くのツールが開発・提供されている。

  • Java開発キット (Java Development Kit、JDK) - Javaアプリケーションの基本的な開発環境。
  • 統合開発環境 (IDE) - アプリケーションを開発できる多機能な開発環境。後述する。
  • Apache Ant - Javaアプリケーションのビルドツール。Apacheソフトウェア財団のプロジェクトによって開発された。コンパイル、バージョン管理システムとの連携、jar、javadoc生成、ファイルのコピー/移動/削除/変換などの一連の処理を自動化して効率的に実行する。makeと同種のツールであり、XMLファイルにビルドの規則を記述する。Java以外の言語によるアプリケーション開発や、アプリケーション開発以外の用途にも使うことができる。
  • Apache Maven - Javaアプリケーションのプロジェクト管理ツール。Apacheソフトウェア財団のプロジェクトによって開発された。
  • JUnit - Javaアプリケーションの単体テストフレームワーク。単体テストを自動化する。xUnitの一種である。テスト駆動開発を支援する。

統合開発環境

Javaプログラムを開発できるいくつかの統合開発環境 (IDE) を示す。

  • Sun Java Studio Enterprise(2005年11月9日に無料化)。Sun Java Studio Creator(2005年11月9日に無料化)。Windows版、Linux版、Solaris版、Mac OS版。NetBeansにサン・マイクロシステムズがいくつかのモジュールを加えた環境。
    • Sun Java Studio Enterprise Sun Java Studio Creator
  • NetBeans - Sun Java Studio Enterprise のオープンソース版ともいえる。サン・マイクロシステムズ。オープンソース。Windows版、Linux版。Solaris版、Mac OS版。
    • NetBeans.org NetBeans.jp
  • Borland JBuilder - ボーランド。Foundation版は無料で入手できる。Windows版、Linux版。Solaris版、Mac OS版。
    • JBuilder
  • WebSphere Studio - IBM。Eclipseの上位版ともいえるもの。WebSphere Application Server と統合されている。Windows版、Linux版。Solaris版、Mac OS版。
    • WebSphere開発ツール
  • Eclipse SDK - Eclipse財団 (以前はIBMが管理していた)。Web Sphere Studio のオープンソース版ともいえる。Windows版、Linux版、Solaris版、Mac OS版。
    • eclipse.org (英語) EclipseWiki (日本語)
  • JDeveloper - オラクル。機能豊富。Oracle Application Server と統合されている。Windows版、Linux版。Solaris版。2005年6月28日に無料化した。
    • JDeveloper
  • BEA WebLogic Workshop - BEAシステムズ。BEA WebLogic と統合されている。
    • BEA WebLogic Workshop
  • BlueJ - Deakin University (オーストラリアヴィクトリア州) と University of Kent (イングランドケント州) 、サン・マイクロシステムズが共同で開発したフリーソフトウェア、Javaの学習に適したインタラクティブな統合開発環境。
    • BlueJ
  • IntelliJ IDEA - JetBrains が開発販売している商用の統合開発環境。
    • IntelliJ IDEA
  • JCreator - Xinox Software が開発販売している商用の統合開発環境 (無償版も利用可能) 。
    • JCreator
  • Visual J++ - マイクロソフト。Windows版。マイクロソフト独自に仕様を拡張しているため、サンのJavaと互換性は低い。

批判

Javaに対しては、優れた技術だと評価する人々がいる一方で、批判も少なくない。 Javaは、ソフトウェアに関する複雑さを管理する問題に対して、革新的な方法を提供するという目標のもとで、開発された。 多くの人々は、Java技術は、この期待に対して満足できる答えを提供したと評価している。 しかしJavaにも欠点が無いわけではない。 Javaは、どのようなプログラミング作法にも適応しているわけではない。 また、どのような環境や要件にも普遍的に適応しているわけではない。

Javaに対する批判を大まかに記述する。

実行性能

Javaの初期のバージョンでは、CやC++などのネイティブにコンパイルする言語と比べて、とても実行が遅くメモリの消費が激しいとして、批判されることが多かったが、近年のバージョンでは改善されてきている。 近年のJava仮想マシンで採用しているジャストインタイムコンパイラや動的再コンパイルの実行性能は、従来の言語のネイティブコンパイラとほぼ同じ水準の実行性能を達成することがある。またJavaの自動ガーベジコレクションの技術も向上している。こうした事情から、Javaの実行性能については、議論の対象となっている。

ルックアンドフィール

ルックアンドフィールに関して、JavaのSwingのツールキットを使ったグラフィカルユーザインターフェース (GUI) を備えたアプリケーションの既定のルックアンドフィールが、従来のネイティブなアプリケーションとは大きく異なるため、エンドユーザの人々にとってJavaのGUIアプリケーションはなじみにくいと批判されることがある。Javaではプラグイン可能なルックアンドフィールの機構を備えており、サンはWindows、Mac OS XおよびMotifの各ルックアンドフィールのクローンを提供している。そのため、Swingの既定のルックアンドフィールではなく、プラットフォームネイティブと同様のルックアンドフィールでJavaのアプリケーションを動かすよう指定することができる。しかしエンドユーザにとってこの指定方法は簡単ではないと指摘されることがある。

言語仕様の設計

言語仕様の設計に対する批判をいくつかの側面から述べる。

  • Javaの設計者は、他のプログラミング言語では備えているいくつかの機能をJavaから排除した。こうした設計上の判断については賛否が分かれている。
    • 多重継承
    • 演算子のオーバーロード
    • プロパティ - Delphi と C# において実装されている機能
  • Javaは、純粋なオブジェクト指向プログラミング言語ではないとして、批判されることがある。Javaの変数値には、スタック領域に割り当てられる基本型 (primitive type) と、ヒープ領域に割り当てられる参照型 (reference type; オブジェクトの型) がある。Javaの設計者は、実行性能上の理由から、意図的に基本型をJavaに導入した。ただし、J2SE 5.0 以降ではオートボクシングが導入され、プログラマは基本型の変数を参照型の変数 (プリミティブラッパークラスのオブジェクト) であるかのようにプログラミングすることができるようになった。基本型の変数と参照型の変数との間の変換はコンパイラによって自動的に行われるようになり、ソースコードを読みやすくすることができるようになった。
  • Java は、オブジェクト指向プログラミングという単一のパラダイムに基づいた言語であり、そのことが批判の対象となることがある。J2SE 5.0 では、メソッドとフィールドの static インポートを行えるようになり、手続き的なパラダイムをいくぶん良い形で取り込んだと言及されることがある。しかし static インポートを不用意に使うとソースコードを判読困難にする可能性がある。サン/JCPは static インポートを適切に使用する方法を説明している。

クラスパス

一般に、Javaプログラムを実行する際、-classpath オプションを使用するか、環境変数クラスパス (CLASSPATH) を必要に応じて適切に設定する必要がある。環境変数クラスパスを指定すると、既定のカレントディレクトリという設定が上書きされる。したがって、環境変数クラスパスを変更するソフトをインストールするなど設定を変えられた場合は、Java実行環境は正しくJavaプログラムを実行することができなくなることがある。このためJavaを使い始めた人々は、クラスパスについて戸惑うことがある。サンは -classpath オプションを指定する方法を推奨している。

移植性・互換性

Javaは高い移植性と互換性を実現するべく開発されており、ある程度の水準まで達成しているが、課題が残っている。Javaのバージョン間の下位互換性・上位互換性が完全ではないことが問題として議論の対象になっている。Javaでは高い移植性を保っているため、一部のプラットフォームにしかない独自の機能はJavaからは使えない。


inserted by FC2 system