Java言語概論

目次
  1. プログラミング言語とは
  2. Java言語の特徴
  3. Javaの開発環境・実行環境
  4. Javaの実行方法

1 プログラミング言語とは

プログラミング言語とは、プログラムを記述するための言語である。ここでは、プログラムとは、コンピュータに実行させる処理の記述のことである。 Java はプログラミング言語の1つである。コンピュータの歴史はプログラミング言語の歴史とも言え、非常に多くの種類のプログラミング言語が存在する(C, C++, Fortran, COBOL, Lisp, ML, Scheme, Prolog, BASIC, Smalltalk, などなど)。実験的な言語や、今やほとんど使われなくなった言語、特定の分野や利用に特化した言語など種類や目的も多彩である。日本語などの自然言語に対して、プログラミング言語は人工言語と呼ばれる。

プログラムとはコンピュータに実行させる処理の記述のことである。ソフトウェアプログラムとも言う。ご存知の通り、コンピュータの電子頭脳、つまりCPU(Central Processing Unit - 中央処理装置)は半導体による高密度集積回路によって構成されている。回路なので、つまるところ電気が通るか通らないか(または出圧が高いか低いか)という2つの状態の組み合わせで動くのである。この電圧が低い状態を「0」、電圧の高い状態を「1」と仮定した場合、0と1だけを利用し、つまり2進数のみでコンピュータに処理を行わせなければならない。

0と1のみで処理を記述するプログラム言語を機械語(machine language マシンランゲージ)と呼ぶ。機械語はもっとも低レベルなプログラム言語(low level language)、つまりコンピュータに近い仕様の言語である。機械語はその対象の演算装置やシリコンチップの種類ごとに特化されており、違っている。実際にプログラマ(つまり人)によって直接機械語でプログラムを組む場合もまれにある。この場合、さすがに0と1だけで表示や入力を行うのは効率が悪いため、0と1の2進数を0から9そしてA(10)からF(15)を入れた16の記号を用いて16進数で表示や入力を行う。

しかし16進数の機械語は覚えにくい上に読みづらいため、16進数の機械語の命令を簡単なアルファベットのニューモニック(主に3文字)で記述する言語が考えられた。これがアサンブリ言語(assembly language)である。アセンブリ言語を機械語に組みなおす(assemble アセンブル)するプログラムをアセンブラ(assembler)と呼ぶ。アセンブリ言語も機械語と1対1でマッピングしているため、対象の装置ごとに仕様が異なる。一昔前はアセンブリ言語でプログラムすることが普通に行われたが、今ではあまり一般的ではなくなり、特殊な状況でのみ利用されるようになった。

機械語やアセンブリ言語の欠点は、プログラム実行するまでプログラムの処理ミスや記述ミスに気がつかないことである。機械語やアセンブリ言語で書かれたプログラムは直接CPUに命令を出すため、間違いがあった場合の影響は劇的であり、そのような間違ったプログラムによりコンピュータはよく「暴走」した。一般的には「暴走」したコンピュータを止める方法は無く、コンピュータのリセットや電源切断が必要になった。これが開発者にとって不便であったことは想像しやすい。

これらの背景を受け、人が覚えやすく、プログラミングの定型処理を簡便化して組みやすくし、間違いなどをある程度自動的に発見してくれるプログラミング言語の必要性により高級プログラミング言語(または高水準言語、高次言語、高レベル言語)、つまり人の言葉に近い言語が次々と生まれた。高級言語は、人間に扱いやすい表現方法をもたせたプログラミング言語のこと。Java言語やC言語は高級言語である。高級言語は人に読みやすい言語であり、機械語に変換しなければ実行できない。

高級プログラミング言語は大きく分けて、翻訳型(compiled language コンパイル型言語)と通訳型(interpreted language インタプリタ型言語)の2種類に分別ができる。翻訳型(コンパイル型)は、プログラマつまり人が書いたソースコードを、コンピュータが処理できる機械語に一度の翻訳(コンパイル)して、その翻訳した結果をコンピュータが後で実行する。翻訳プログラムであるコンパイラ(compiler)によるコンパイル作業には時間がかかるが、その代わりにコンパイルした結果を保存しておけば、2回目以降は直接翻訳結果のオブジェクトコードや実行プログラムを呼び出すことができるため、実行処理が早い。また、一度にすべてのソースコードを翻訳するため、実行前にソースコードの間違い(エラー)を発見することができる。例えば、CやC++はコンパイラ方式である。

通訳型(インタプリタ型)もプログラマがソースコードを書く点は同じであるが、インタプリタ型ではプログラムの実行前にすべてのソースコードを機械語への翻訳するのではなく、インタプリタが機械語への通訳を行いながら、その通訳された結果を逐次実行するのである。インタプリタ型の利点としては、全てのソースコードを一度に翻訳するわけではないため、コンパイルの手間と時間を省くことができ、ソースコードを少しずつ何度も変更するプロトタイピングなどを効率良く行うことができる。また、実行時に機械語に通訳するため、実行する環境(対象となるハードウェア)に依存するオブジェクトコードがなく、プラットホームからの独立性が高い。また、インタプリタ言語では、プログラムを必ずはじめから実行する必要がなく、プログラムの途中や特定の部分だけを実行したり、特定の部分のソースコードのみを更新してプログラム実行を継続したりするなど、柔軟な実行方法が行える。例えば、Lisp 、ML や BASIC などは主にインタプリタ方式である。

その他のプログラミング言語の分類方法としては、手続き型言語(procedural language)、非手続き型言語(non-procedural language)、関数型言語(functional programming language)、論理方言語(logic programming language)などがある。

プログラミング言語=構文+意味的制約+意味 プログラムの構文:構文単位の組み合わせ方には規則がある。その規則を構文規則(syntax)または文法という。

プログラムの意味的制約:たとえば構文規則に合っていても、誤ったプログラムがある。例えば、10 + true は誤ったプログラムであるが、これは構文規則とは別に「論理値は足し算できない」という規則があるからである。

プログラムの意味:プログラムの動作結果をそのプログラムの意味(semantics)という。例えば、式 10+20+x の意味は「変数xの値に30を足した値」である。

2 Java言語の特徴

Java言語は現在のソフトウェア産業のニーズとの高いマッチングにより、1995年に発表されてからの短い期間にまたたくまに普及し、ネットワークシステムの主要な開発言語となるまでになった。Java言語の優位性は数多くあるが、ここではJava言語の主な特徴について述べる。

Java言語は、本格的なオブジェクト指向言語である。Java以前にもオブジェクト指向型プログラミング言語はあった。C++、Objective Pascal (Delphi)、SmallTalkなどがそうである。C++やObjective Pascalは、もともと手続き型であったプログラミング言語(C言語およびPascal言語)にオブジェクト指向を追加したため、実装がすっきりしていない部分があり、作成するソフトウェアが自然なオブジェクト指向設計にならない場合がある。SmallTalkは逆に完全すぎるオブジェクト指向のため、性能面や利用面で難点があった。Java言語はもともとオブジェクト指向を目標とした言語のため、設計も非常にすっきりしており、かつ実際の利用も考慮した仕様となっているため、オブジェクト指向言語として現実的な選択を取ったといえる。

Javaはコンパイラ・インタプリタ型言語である。コンパイル型言語の利点と、インタプリタ型のアドバンテージの両方を併用した、ハイブリッド型とも言える。Javaでは、コンパイル型の利点である、コンパイル時のソース上の正確なエラーチェックや、コンパイルされたオブジェクトコードの最適化が可能である。また、インタプリタ型の利点である、実行ハードに依存しない、プラットホーム独立性も実現している。

インタプリタ型の利点であるプログラムのプラットホーム独立性により、Java言語はマルチプラットホーム、つまり多くのOSやハードウェアプラットホームでの実行を可能としている。これは、Javaのインタプリタである JVM(Java Virtual Machine Java仮想マシン)の仕様が厳密に定義されているためでもあり、このためコンパイルしたクラスファイルは、どのプラットホーム上のJVMでもそのまま実行することができる。Javaの元の開発であるSun Microsystems(現 Oracle Corporation)では、"Write Once, Run Everywhere" (一度書いて、どこでも実行)をキャッチフレーズにしていた。 JVMは通常のパソコン以外でも、携帯電話やスマートフォンでも動作する。

Javaは言語設計の段階からネットワークとの親和性が考慮された。発表当初からネットワークを利用するための基本クラスが準備されており、ネットワーク機能を利用したアプリケーションの作成が容易になっている。またJavaにはネットワークセキュリティ機能がはじめから備わっているため、安全にネットワークアプリケーションを利用することができる。また、Javaのバージョンアップのたびに様々なネットワーク機能が追加されており、ネットワーク機能が現在のソフトウェア開発にいかに重要かを表している。

Java言語のネットワーク機能の一部として、アプレット機能をあげることができる。アプレットとは、Webブラウザで表示されるページの一部として動作するJavaプログラムのことである。これはWebブラウザにJavaインタプリタ(JVM)機能を追加することにより実現する。Java発表当初は、静的なWebページにダイナミックな機能を追加するこの革新的な機能がメディアで広く取り上げられ、Java言語の普及に大きな影響を与えた。現在ではアプレット以外の方法でもWebページ内にプログラムを埋め込む方法がいくつも提案されているが、機能面、利用し易さ、セキュリティなどによりアプレットが選択される場合が多い。

Javaでは、ガーベジコレクション機能(garbage collection)により自動的にメモリ管理が行われる。C言語などでは、メモリの操作による後処理をプログラム中で行う必要がある。よって、C言語ではプログラマはメモリの割当てと解放を明示的に行わなければならない。しかし、C言語などで作成されたプログラムでの問題の多くがこのメモリ管理に関するものであることを考えると、いかにメモリ管理が難しく、かつ重要な問題であることが理解できる。それに対して、Javaはガーベジコレクション機能によって開発者からメモリ管理を開放し、結果としてより安定したソフトウェアを開発できる環境を提供している。ガーベジコレクションがこれまであまり普及してこなかった理由としてガーベジコレクションのメモリ管理アルゴリズムの複雑さと非効率があげられるが、Javaに関しては、ガーベジコレクション開発には多くの時間が費やされ、非常に完成度の高いガーベジコレクションを実現している。

Javaでは標準で汎用的な描画機能を提供するクラスライブラリが含まれている。これにより、プラットホームに依存しない、グラフィカルなアプリケーションを容易に開発することが可能になった。またGUI(Graphics User Interface)部品(ボタン、テキスト入力、メニューなど)も多く標準で提供されているため、GUIアプリケーションの開発も非常に少ない開発で行うことが可能である。汎用描画クラスライブラリとしては、AWT (Abstract Window Toolkit)、Swing、Java2D、Java3D などがある。

Java言語の文法はC言語やC++言語に類似している。実際、Javaの言語仕様はC++の言語仕様を洗練したものになっている。C言語は従来のソフトウェア開発言語の主流であったため、多くのCプログラマがおり、Javaではこれらの開発者がスムーズにJava言語へ移行できるように考慮されている。しかしJava言語ではCやC++での開発で問題の多かった点を改良している。例えば、CやC++では必須であり、かつ多くの問題の原因であったポインタ操作は、Javaでは許されていない。これにより、ポインタ管理の問題を回避することが可能になった。

Javaはマルチスレッド(multithread)機能を言語仕様として持っている。マルチスレッド機能とは、一つのプログラムを複数の細かいスレッド(thread)と呼ばれるプログラム制御に分割し、並列実行させるものである。この機能によって、複数の機能を別スレッドとして同時に実行することができる。これは、サーバプログラムなどを作成するときに、複数のクライアントと同時に通信が行えるということである。

3 Javaの開発環境・実行環境

Javaプログラミングの一連の作業を行う環境がJava開発環境である。Javaの開発元であるOracle Corporation社は、インターネット上において無償でJava開発環境を提供している。この開発環境には、Javaのコンパイラ、インタプリタ(JVM)、簡易的なデバッガなど、コンパイルと実行に必要な機能が備わっている。ただし、これらのツールは全てコマンドラインから利用する文字ベースのツールである。グラフィカルな環境でのIDE(Integrated Development Environment - 統合開発環境)はOracleのNetBeansやEclipseなど、様々な製品がインターネットで公開されている。

Oracleが無償で提供するJava開発環境は、現在Java SE Development Kit(JDK)と呼ばれる。Java SE は Java Standard Edition の略である。JDKには、Javaの実行に必要なインタープリタ(JVM)に加え、Javaの開発に必要なコンパイラ、デバッガ、ドキュメント生成ツールなどが含まれている。

Oracleは、Javaの実行にのみ必要機能を集めた、Java実行環境も無償で提供している。この実行環境は、JRE (Java Runtime Environment)と呼ばれる。JREには、コンパイラやデバッガなどの開発に必要なツールが省かれており、Javaの実行に必要な最低限のファイルのみが提供される。

Java EE は、Java Enterprise Edition の略であり、企業向けアプリケーションの開発および配備に使用する環境。Java EE プラットホームは、Web ベースの多層アプリケーションを開発するための機能を提供する一連のサービス、API (アプリケーションプログラミングインタフェース)、およびプロトコルから成る。Oracleは、Java EEの実装として、Java EE SDK (Software Development Kit) を提供している。

Java Micro Edition (Java ME) とは、様々な IoT (Internet of Things) デバイス、マイクロコントローラ、センサー、ゲートウェイ、携帯電話、デジタルセットトップボックスなど、幅広い消費者製品をターゲットに最適化された Java 開発および実行環境である。

開発・実行環境とは少し違うが、Java SE SDKにはソースコードからAPIドキュメントを自動的に生成してくれるツール javadoc が含まれる。javadoc は、決められた形式のコメントをソースコードに埋め込むことにより、ソースコードから自動的にJava標準のAPIドキュメントのhtmlドキュメントを生成することができる。

4 Javaの実行方法

Javaに限らず、プログラミング言語で書かれたプログラムは、機械語(コンピュータが直接実行できる言語。マシン語ともいう)に変換されて実行される。この変換の仕方は大きく分けてコンパイラ方式とインタプリタ方式がある。

Javaはコンパイラとインタプリタの両方を用いるコンパイラ・インタプリタ方式である。 JavaはJavaコンパイラ(javacコマンド)で.javaファイルを.classファイルに変換する。 .classファイルの内容をバイトコードと呼び、 Javaインタプリタ(javaコマンド)はこのバイトコードを機械語に変換しながら実行する。

なぜ、このようなまどろっこしいことをするのであろうか。 それは実行速度と移植性のバランスを取ったためだと思われる。 インタプリタ型は移植性を高くするのに向いているが実行速度が遅い。 対してコンパイラ型は、コンパイルして機械語にしたコードは他の環境では動かない。 そこでJavaでは環境に依存しないバイトコード(中間コードとも呼ばれる)を設計し、バイトコードまではコンパイルし、バイトコードはインタプリタで実行することでそこそこの実行速度を持ちながら移植性の高さを保つことに成功した。 Javaはコンパイラとインタプリタの良い面を取り入れたハイブリッドな言語と言える。

Javaはコンパイラ・インタプリタ方式を取っていることは説明した。Java SE SDKには、Javaコンパイラとして javac コマンドが含まれる。Javaでは、コンパイラもJava言語で書かれている。javac コマンドの基本的な呼び出し方法は以下である。

javac ソースファイル名
例) javac HelloWorld.java

注意しなくてはならないのは、ソースコードで定義したクラス名と、そのファイル名が一致しなくてはならない点である。すなわち、一般的にはクラスごとにファイルを分ける必要がある。これは、ソースコードの管理の面からはマイナスにはならない。javacコマンドの便利な特徴として、コンパイル対象のソースコードが参照している外部クラスファイルも対応するソースコードが存在し、かつそのソースコードがクラスファイルより新しい場合(つまりコンパイルを必要としている場合)、自動的に参照しているクラスもコンパイルする。これによって、CのようにMakefileを利用しなくても、複数のソースコードを一度にコンパイルすることが可能である。
javacコマンドは高度なエラーチェック機能を持っているため、コンパイラは高い精度でソース上のエラーを正確に発見することが可能である。また多くの利用者にはうれしい機能として、コンパイルエラーを日本語で表示してくれる。
コンパイラは、JVM(Java Virtual Machine)で動作する中間コード(バイトコード、クラスファイル)を .class の拡張子で作成する。クラスファイルは、クラスごとに別ファイルとして生成される。

javaの実行は、javaコマンドで行う。javaコマンドは、JVM(Java Virtual Machine)を起動し、コンパイラにより作成されたクラスファイルを読み込み実行する。javaコマンドの基本的な利用方法は以下である。

java クラス名
例)java HelloWorld

ここで注意するべき点は、実行するクラスファイルの .class 拡張子は除いた形で指定する必要がある。

Jarとは、Java標準のアーカイブ形式である。Jarを利用することにより、複数のクラスファイルやリソース(画像やアイコンなど)を一つのファイルに圧縮することができる。Java SE SDKには、Jarファイルを圧縮・展開するためのツールとすて、jarコマンドが含まれる。Jarで固められたアーカイブは、そのままアプレットとしてやjavaコマンドで実行することが可能である。Jarで実行に必要なファイルを一つにまとめることにより、アプレットでのネットワークからの実行や、アプリケーション配布などが容易になる。 javaコマンドの場合は、-jarオプションで実行することができる。

java -jar Jarファイル名
例)java -jar HelloWorld.jar