本章では少し趣向を変えてJavaプログラムのソースファイル全体の構造、コンパイルと実行のプロセス、およびよく使われるJava用語について説明します。

パッケージ

Javaプログラムの構成単位はクラスですが、クラス名だけで管理していると、すぐに名前の衝突が発生します。 パッケージはこれを防ぐために用意された仕組みです。 すなわち関連したクラスをまとめて小包(パッケージ)として管理します。 外部に公開するクラスのみをpublicとして宣言し、内部だけで使うクラスは外から隠蔽します。 外部に公開したクラスを呼び出すには、次のようにパッケージ名の後にピリオド( . )を付けて、その後にクラス名を記述します。

			パッケージ名.クラス名
		

パッケージの階層

パッケージ名自身も名前が衝突しないように、階層化が可能になっています。 例えば

		
			java.util.Calendar
		

はjavaパッケージの中のutilパッケージの中のCalendarクラスを示しています。 これをクラスの完全限定名と言います。 これは次のようにしてに使います。

		
			java.util.Calendar cal = java.util.Calendar.getInstance();	// ☆
		

独自パッケージ

上の例はJava言語が標準的に提供しているパッケージでしたが、開発者が独自にパッケージを作ることもできます。 それには、Javaソースの先頭に、次のように書きます。

	
			package mypackage;
		

packageは独自のパッケージを宣言する旨のキーワードです。 次のmypackageは独自に付けたパッケージ名です。 パッケージ名も命名規約にしたがう必要があります。 これによってこのソースファイルに含まれるすべてのクラスがmypackageというパッケージに収納されることになります。

パッケージとアクセス制御

前述のように外部に公開するクラスにはpublic属性を付けます。 publicが付けられるクラスは、1つのJavaソースファイルで1つに限られます。 public属性はクラスのメソッドにも付けることができます。 これについてはクラスの章で説明します。

パッケージ名の一意性

パッケージ名を階層的に作れたとしても、全世界の人が作るJavaのパッケージ名の一意性の保証は困難です。 そこでJavaの言語仕様は、作成したプログラムを広い範囲に公開する場合はインターネットのドメイン名を使って一意性のあるパッケージ名を付けるように主張しています。 あなたが abc.co.jp というドメイン名を持つ組織に所属していれば以下のようなパッケージ名を付けることになります。

		
			jp.co.abc.組織内の一意名
		

インポート文

上の例(☆)で示したように、いつも完全限定名を使っていては大変です。 そこでインポートという仕組みが用意されました。 まずソースファイルに 01: のように書いておきます。 すると、☆は 02: のように、java.util の部分を省略できます。

	
			01:	import java.util.Calendar;
			02:	Calendar cal = Calendar.getInstance();
		

また、03: のように * を使うと、java.util 内のすべてのクラスを使うことができます。
ただし、これは java.util の直下にしか有効ではありません。 例えば java.util.jarパッケージ内のクラスも使おうとすると、04: のような記述も必要です。

	
			03:	import java.util.*;
			04:	import java.util.jar.*;
		

ソースファイルの構成

ソースファイルの例を示します。 以下は A.java と言うファイル名の内容です。

	
			--A.java---------------------------------
			package mypackage;		// package文
			import java.util.*;		// import文
			import java.io.*;		// import文
			public class A { 		// クラス定義
				…
			}
			class B {			// クラス定義
				…
			}
			-----------------------------------------
		

Javaソースの規約 ★

Javaのソースファイルは以下の条件を守らねばなりません。

  • package文はファイルの先頭に記述する。 package文は0または1行である。
  • 引き続いてimport文を記述する。 import文は0~複数行記述できる。
  • 次にクラス定義を記述する。 1ソースファイルに複数のクラスを記述できるが業務で使うときは1ソースファイル1クラスが望ましい。
  • publicが指定できるクラスは1つのソースファイルに0または1クラスである。
  • publicを指定したクラス名とソースファイル名は同じでなければならない。
  • ソースファイルの拡張子は .java とする。
  • ソースファイルにmainメソッドが存在しなくてもかまわない。

コンパイルと実行

Javaのコンパイルはjavacコマンドを使い次のように行います。

	
			javac A.java
		

コンパイルが正常に終了すると、Java独自の中間言語(バイトコード)で書かれた、クラスファイルができます。 クラスファイルはソースファイルのクラスの数だけできます。 A.java には2つのクラスがあったので次のようなファイルができます。

	
			A.class
			B.class
		

実行

コンパイルの結果できたクラスファイルは次のようにして起動します。 mainメソッドをもたないクラスは起動できません。 このとき、java A.class と指定するのではなく、拡張子 .class は不要ですので注意してください。

	
			java A
		

パッケージの例 ★

Javaが標準的に提供しているパッケージの内、代表的なものを示します。 java.lang は最も基本的なパッケージであり、暗黙的にimportされているので、明にimportしなくても使うことができます。

	
			java.lang		Javaプログラム言語の基本的なクラスを提供
			java.io			システム入出力の機能を提供
			java.util		基本的なユーティリティを提供
			java.sql		データベースにアクセスして処理するための機能を提供
			java.net		ネットワークアプリケーションのためのクラスを提供
		

コメント

Javaではプログラムの中に機能や目的など、後で見るときに役立つメモを書いておくことができます。 これがコメント文です。 コメント文の部分はプログラムは何もしないで読みとばしますので、プログラムの動作に何も影響を与えません。

Javaのコメント文には次の3種類があります。 01: はこれまでも使ってきました。 02: は行内の一部や、逆に長い行に渡ったコメントを記述するのに有効です。 03: は 02: の一部ですが、この形式でコメントを書いておくと、javadoc(ジャバドック)というツールを使ってドキュメントを作成することができます。

	
			01:	//		行末までのコメント
			02:	/* … */	範囲指定型(複数行可;ネストは不可)
			03:	/** … */	ドキュメント自動作成用のコメント
		

アノテーション

アノテーションはコメントと同じようにプログラムの動作に直接影響を与えません。 ただしコメントと違ってプログラムから読み取ったりコンパイラーに影響を与えたりすることができます。 アノテーションは先頭に @ を付けて表します。 以下にアノテーションの使用例を示します。

メソッド名の前に以下のようなアノテーションを付加すると、そのメソッドがオーバーライドメソッドであることを示します。 このアノテーションが付いているのにもかかわらず、 そのメソッドがオーバーライドしていないとコンパイルエラーになります。 これによりタイプミスなどによるメソッド名や引数の型の間違いを検出することができます。

	
			@Override
		

また、クラス名の前に以下のようなアノテーションを付けると、そのクラスがEJBのステートレスセッションBeanであることを示します。 EJBコンテナはこれを認識して対応する処理を実行します。

	
			@Stateless
		

アノテーションには引数を取るものもあります。 例えばクラス名の前に次のように記述すると、コンパイラーが出す unchecked という警告を抑止(SuppressWarning)することができます。

	
			@SuppressWarnings("unchecked")
		

これらはアノテーションのごく一部の例です。 アノテーションには多くの種類があり、自分で定義することもできます。

アサーション(表明)

アサーションは実行時にある条件をチェックし、その条件が成立しないとAssertionError例外を発生させる構文です。 この仕組みを使うことでデバッグが容易になります。 アサーションの例を示します。

	
			assert x >= 0: "x は正のはず! x = " + x;
		

この文は変数 x が 0 以上であることを表明しています。 実際に 0 以上であれば何も起きませんが、そうでないと例外を発生し「:」以降の内容を表示します。 x が -1 の時にこの文が実行されると次のように表示されます。 AssertTest.javaはこのコードが記述されているファイル名、12はこの文のファイル内の行位置です。

	
			Exception in thread "main" java.lang.AssertionError: x は正のはず! x = -1
			at AssertTest.main(AssertTest.java:12)
		

このように、要所要所にassert文を埋め込んでおき、実行時に実際にそれを確認することで、スムースなデバッグが可能になります。 なお、アサーションを有効にするには実行時に次のように -ea オプションを指定する必要があります。SuppressWarning)することができます。

	
			java -ea AssertTest
		

ガベージコレクション(未使用領域の返却)

Javaでは使われなくなった領域(誰からもポイントされなくなった領域)を探して、共用のメモリ領域(ヒープメモリ)に自動的に返却する処理を行っています。 この仕組みをガベージコレクション(ゴミ集め)と言います。 このためC++では大きな問題となっていたメモリリーク(メモリの開放し忘れ)がJavaでは発生しにくくなりました。

ただし、ある領域が未使用となったからといって、必ずしもガベージコレクションが実行されるとは限りません。 ガベージコレクションは、処理の合間をぬって実行されます。 ある特定の未使用領域に対してガベージコレクションが実行されるかどうか、またいつ行われるかは、ガベージコレクションを行うプログラムに任されています。

※ メモリリーク問題はJavaでは大きく改善されましたが、まだ次の問題があります。
(1) ガベージコレクションが不定期に実行されるので、突然性能が悪化することがある。
(2) プログラマーが使い終わったメモリの解除そのものを忘れると、やはり返却されない領域が少しづつたまりメモリ枯渇を起こすことがある。

Java用語集 ★

クラスパス

クラスパスは、Javaが使用するクラスライブラリーなどの場所を検索する際の、場所を示すリストです。 クラスパスで指定した範囲で使用するクラスが検索できないと、 コンパイルまたは実行時にエラーが表示されます。 クラスパスを変更するには、コマンドの -classpath オプションを使用するか、またはOSのCLASSPATH環境変数を使用します。

jarファイル

jar(ジャーと読む)はJava ARchiveの略で、Javaで標準的に使用されている圧縮ファイルです。 クラスファイルなどがZIP形式圧縮されて格納されています。 jarファイルになっていれば、Javaが自動的に展開して実行してくれます。 jarファイルは「jar」というコマンドで作成できます。

javadoc

javadocとはJavaのソースファイルからJavaのリファレンスマニュアルを生成してくれるコマンドです。 ソースファイルに決まった形式でコメントを書いておくと簡単にリファレンスマニュアルができます。 ソースを修正したが、ドキュメントは古いままということがおこりにくくなります。

☆☆☆コラム☆☆☆ ---- Java関連の参考Webサイト

ページの先頭へ