第10回 Javaのクラスをグループ化するパッケージ
平井玄
2003/10/11
|
今回の内容
|
クラスを使ったプログラムのメリットは、一度作ったクラスを再利用できることです。再利用できるのはプログラマ自身が作ったクラスだけではなく、他人が作ったクラスでも構いません。
Javaを始めたばかりの皆さんは、「ほかの人が作ったクラスを利用する機会なんてあるのだろうか?」と思われるかもしれません。しかし、この連載の読者の皆さんはすでに他人が作ったクラスを再利用しています。そのクラスとは、String型のことです。
String型はJavaというプログラム言語の仕様に組み込まれた極めて基本的なクラスですが、クラスである以上、String型というクラスの定義や、文字列を扱うためのメソッドを用意しなければなりません。String型のような基本のクラスは、Java言語を作った人たちによって作られました。
String型のクラスの定義は、第1回「Java2 SDKで学習の準備」で少しふれたように「C:\Program Files\j2sdk1.4.1」にある「src.zip」という圧縮ファイルの中にあります。圧縮ファイルの中の「java/Lang」フォルダにある「String.java」というファイルです。圧縮ファイルの中からString.javaをデスクトップなどにドラッグ&ドロップし、エディタなどで開いてみてください。はじめにコメント文がありますが、以下のようなString型の定義があるはずです。これまでString型を何げなく使ってきましたが、この連載で定義したHTMLDocumentなどのクラス同様、メンバ変数やメソッドの定義が並んでいます。
public final class String |
上記のメンバ変数やメソッドに付いているprivate、publicというキーワードの意味は前回「クラスのメンバに利用制限を付与するアクセス制御」で紹介したとおりです。簡単におさらいすると、privateを付けるとクラス内部の作業用になり、publicはこのクラスのインスタンスを生成したプログラムなど、外部から利用できる変数やメソッドになります。
この連載において、これまでは単に文字列を操作するためのクラスとしてString型を使ってきましたが、String型の大きな特徴は一度設定した文字列は後から変更できない読み取り専用の型であることです。文字列はchar型配列のメンバ変数value[]に格納されます。また、value[]に格納された文字列の長さはint型のメンバ変数countに格納されます。
ただし、value[]もcountもprivateに指定されていますので、クラスの外部からはアクセスできません。そこで、文字列の長さを調べるlength()のようなメソッドを使って間接的に文字列の長さを取得するわけです。別のいい方をすると、String型のソースコードを見たことのないプログラマは、length()がどのように文字列の長さを調べているのか分かりません。まさか内部にcountというメンバ変数があって、length()は単にcountの値を返しているだけとは気付かないわけです。
Javaのようなオブジェクト指向言語ではクラスを継承させることで元のクラスの機能を拡張できますが、サブクラスを定義するプログラマでさえ、スーパークラスがどのように定義されているのか、詳細を知る必要はありません。クラスという道具を使いこなすには、それぞれのクラスがどのような機能を持っているかを理解すればよく、その道具はどのようにできているのかは知らなくてよいのです。
このことをオブジェクト指向の世界では「カプセル化」といいます。クラスの内部構造は隠してしまって、プログラマは公開されたメンバ変数やメソッドだけを使ってください、ということです。従って、何かのクラスについて知りたいプログラマは、クラスの定義ではなく、クラスのpublicなメンバ変数とメソッドとしてどんなものが用意されているのか調べればよいのです。
ただし、カプセル化されているのだから、クラスの定義なんて知らなくていい、とは思わないでください。確かにプログラムを作るうえではクラスの定義を知っている必要はありません。しかし、Javaを作った人々が書いたソースコードを眺めることは、それだけで勉強になります。ソースコードを眺めることをきっかけに、初心者から中級者、中級者から上級者にステップアップすることもあると思います。クラスの説明をどんなに読んでも分からなかったことがソースコードを読んだら分かったということもよくあることです。
| パッケージとは? |
Javaが提供しているクラスや他人が作ったクラスを再利用する場合、クラスの名前に注意しなければなりません。String型のような基本的なクラス名と重複するようなクラスは作った方に責任がありますが、この連載で作成したHTMLDocumentのように、Javaの言語仕様には含まれないけれど、誰が作ってもいかにも同じ名前が付きそうなクラスはいくつもあります。そこでjavaには「パッケージ」という考え方があります。
説明の前に実際にパッケージを作ってみましょう。
| パッケージ宣言付きのHTMLDocument |
package jp.co.atmarkit.java; |
パッケージの保存からコンパイルまでの手順は以下のとおりです。
| (1) | HTMLDocument .javaとして、C:\Documents and Settings\<ユーザー名>\My Documents\My Java Applications\jp\co\atmarkit\javaに保存する |
| (2) | C:\Documents and Settings\<ユーザー名>\My Documents\My Java Applications\jp\co\atmarkit\javaというフォルダを作る |
| (3) | C:\Documents and Settings\<ユーザー名>\My Documents\My Java Applications\jp\co\atmarkit\javaに移動して、HTMLDocument .javaをコンパイルする |
C:\DOCUME~1\MYDOCU~1\MYJAVA~1>\JP\CO\ATMARKIT\ |
次に、パッケージとして保存したHTMLDocumentを利用するプログラムを作成します。
| HTMLDocumentを利用するプログラム |
import jp.co.atmarkit.java.HTMLDocument; |
こちらのファイルはいつもどおりC:\Documents and Settings\<ユーザー名>\My Documents\My Java Applications\にPackageTest.javaの名前で保存してからコンパイルします。
C:\DOCUME~1\MYDOCU~1\MYJAVA~1>\JP\CO\ATMARKIT\ |
何かを実行するプログラムではありませんので何も起こりませんが、PackageTest.javaにはHTMLDocumentの定義が含まれないのに、HTMLDocumentを利用できたことが分かります。
それでは、はじめから順に説明していきます。
package jp.co.atmarkit.java; |
HTMLDocumentの定義を含むHTMLDocument.javaには、いままでにはない「package jp.co.atmarkit.java」という文があります。「jp.co.atmarkit.java」全体がパッケージの名前になります。続いてクラスの宣言をしています。このとき、クラスはpublicに指定されていますので、「package jp.co.atmarkit.java」というパッケージに所属する「HTMLDocument」というクラスという意味になります。
次にPackageTest.javaとして保存したファイルをもう一度見てみましょう。
import jp.co.atmarkit.java.HTMLDocument; |
冒頭にはこれもいままでなかった「import jp.co.atmarkit.java.HTMLDocument;」という文があります。4行目に出てくるHTMLDocumentのクラス定義はPackageTest.javaに含まれませんが、コンパイルエラーになりません。はじめのimport文によって、コンパイラはHTMLDocumentが「jp\co\atmarkit\java\」にある「HTMLDocument.class」のことだと分かるからです。つまり、パッケージの名前とディレクトリ構造を一致させることで、コンパイラが目的の.classファイルを見つけ出せるようにしているわけです。また、クラス名が同じでも、パッケージ名が異なれば別のディレクトリに保存されることになりますので、同じクラス名でも共存できるわけです。
| パッケージ名とクラス名 |
String型の話に戻りましょう。String.javaのファイルに「package java.lang;」という文があります。
/* |
つまり、String型クラスも「java.lang」というパッケージに所属するクラスなのです。しかし、これまでの連載では「import java.lang.String」などとしないでもString型を利用できました。いったいどうしてなのでしょうか?
実はjava.langというパッケージにはString型や「System.out.println(…)」で登場したSystemのように、Javaの言語仕様そのものといえるクラスが所属しています。あまりにも基本的なので、わざわざ「import java.lang.String」などとしないでも利用できるようになっているのです。
パッケージとクラスの関係では、もう1つ重要なことがあります。それは、正式なクラス名は常にパッケージとの組み合わせで表現されるということです。ソースファイルの中でこそ「String」のようにクラス名単独で登場しますが、あくまでも「java.lang.String」が正式なクラス名です。Java用語では、Stringのような省略形を「単純名(simple name)」、「java.lang.String」のような形式を「完全修飾名(fully qualified name)」と呼びます。
ちょっと分かりにくいので実例を示しましょう。
| 単純名のサンプル |
public class SimpleNameSample { |
単純名を使った上記のプログラムは、以下のように完全修飾名を使っても記述できます。
| 完全修飾名のサンプル |
public class FullyQualifiedNameSample { |
クラス名を名前だとすると、パッケージ名は名字に相当すると考えればよいでしょう。パッケージはディレクトリ構造で管理されるので同じコンピュータ内で競合することはありません。さらに、コンパイラそのものは常にクラス名を完全修飾名で扱いますので、たとえクラス名が同じになることがあっても、パッケージ名は異なりますから、完全修飾名としては区別できるわけです。
コンパイラがクラス名を完全修飾名で扱っていることは、コンパイラが生成する.classファイルをエディタで開くと分かります。以下は「単純名のサンプル」をコンパイルしたSimpleNameSample.classファイルです。
…………………………<init>……()V……Code……LineNumberTable |
単純名で記述したはずですが、.classファイルには「java/lang/String」という文字があるのが分かります。一方、「完全修飾名のサンプル」をコンパイルしたFullyQualifiedNameSample.classファイルは以下のようになります。
…………………………<init>……()V……Code……LineNumberTable |
クラス名と文字列部分は違いますが、バイナリ部分や「java/lang/String」の部分は同じになっていることがわかります。コンパイラ内部で、クラス名は常に完全修飾名で扱われます。しかし、人間にとって完全修飾名は冗長です。そこでクラス名が重複しない限り、importだけで単純名で表記できるようにしているわけです。
なお、import文のクラス名は省略できます。例えば、java.utilに含まれるComparator、ArrayListというクラスを利用したいときに、以下のように記述できます。
import java.util.*; |
アスタリスクはクラス名の代わりに使えます。この場合は、「java.util」というパッケージに所属するクラスすべてを利用する、という意味になります。従って、import文を省略できる「java.lang」パッケージについては、「import java.lang.*」という文が省略されている、とも考えられます。
| パッケージ名の命名方法 |
パッケージが完全修飾名で表したときのクラス名の重複を防ぐ方法であることは分かったと思います。では、パッケージ名の重複はどのように防ぐのでしょうか? Javaで何かを開発しようと思ったら、1人の開発者が1台の閉じたコンピュータで作業するというわけにはいきません。Javaに含まれるさまざまなパッケージや、他人の作ったパッケージを購入して使う場合もあります。このとき、それぞれが勝手なパッケージ名を付けてしまったら、クラス名の重複を防ぐという機能を果たせなくなります。
そこでJavaでは、パッケージ名として所属企業のドメイン名をトップレベルドメイン側から並べ替えてパッケージ名にする方法が推奨されています。はじめに紹介したsrc.zipの中身に、例えば「com/sun/corba」というディレクトリがありますが、これは「corba.sun.com」というドメイン名を逆さまにしたものです。今回HTMLDocumentのパッケージ名にした「jp.co.atmarkit.java」は、「java. atmarkit. co.jp」というドメイン名を逆さまにしたものです。こうすれば、たとえHTMLDocumentというクラス名を使うほかのパッケージがあったとしても、完全修飾名では区別できるわけです。皆さんが自作のパッケージを作る場合は、自社のドメイン名を使うとよいでしょう。
次回は、String型のソースコードを詳しく見ながら、クラスの理解をさらに深めます。
いまから始めるJava バックナンバー
- 第1回 Java2 SDKで学習の準備
- 第2回 Javaの変数の本質を知る
- 第3回 クラスを簡単に理解しよう
- 第4回 クラスの継承の本質を知る
- 第5回 メソッドとコンストラクタはなぜ必要?
- 第6回 Javaプログラムの制御構造を理解する
- 第7回 Javaの制御文を使いこなそう
- 第8回 メソッドの挙動を変えるオーバーライド
- 第9回 クラスのメンバに利用制限を付与するアクセス制御
- 第10回 Javaのクラスをグループ化するパッケージ
- 第11回 Javaのクラスの理解を深める
- 第12回 Javaプログラミングにおけるエラー対処
- 第13回 Javaの例外をスマートに記述する
- 最終回 Javaの抽象クラスとインターフェイス
| 「いまから始めるJava」記事一覧 |
ホワイトペーパー(TechTargetジャパン)
- Android NDKでJNIを使用してアプリを高速化するには (2010/3/17)
C/C++やOpenGL ESといったネイティブコードを使うためのNDKとJNIを紹介し、その使い方や注意点を徹底解説します - 調査の難しい「OutOfMemoryError」事例、5選 (2010/3/11)
Java開発者が避けて通れないメモリ不足エラーの基本的な問題切り分け方法と発生につながる事例、対処法を解説 - 究極の問題解析ツール、逆コンパイラJD-Eclipseとは (2010/3/8)
ライブラリ内で例外が発生! そのクラスのソースコードを調べたい!! 自動で逆コンパイルしてくれる無料Eclipseプラグインがあります - いまさら聞けない「Webサービス」の常識 (2010/2/26)
昨今では企業システムでも使われる「Webサービス」の概念やJava標準のJAX-WSを紹介しJBoss WSでサンプルを作成
|
|
スキルアップ/キャリアアップ(JOB@IT)
スポンサーからのお知らせ
- - PR -
| 「いつかは壊れるサーバ」そんな故障に 迅速で安価に手軽に対応する方法とは? New! |
| 「特権ユーザー」の事件を防げ! 万能権限を持つユーザーの管理方法とは? New! |
| 仮想環境の構築とデータ保護の特効薬?! 実績と信頼性の高いパッケージで安心運用 |
| 仮想環境のバックアップもこれまでどおり 「まるごと取ってまるごと戻す」簡単運用 |
| おばかアプリ選手権、第4弾開催中!! ムダにカッコよくてくだらない作品求ム! |
| 社内ファイルサーバを“クラウド”に統合 VPN直結「クラウド型ストレージ」を紹介 |
| その数、なんと400台以上! グループ内 サーバの「統合管理」によるメリットは? |
| 美人!? まあまあ? 気になる いやし系!! PV急増で「美人時計」がとった手段とは? |
| 進化を続ける富士通ストレージETERNUS DX 製品開発者の自信を裏付けるものとは何か |
| 運用管理の課題を“2つの観点”から分析 ユーザー満足度の高い「仮想環境」とは? |
- - PR -
お勧め求人情報

**先週の人気講座ランキング**
〜CCNA編〜
| ◆ | TomcatやJBossなどAPサーバ環境に関する 情報を集約! “業務”用APサーバ大百科 New! |
| ◆ | 一気に解説! 最新のクラスタストレージ 「RAIDを超えたストレージ基準」……など New! |
| ◆ | クラウド的ユーザー体験の変化は脅威か? 仮想化技術を使いこなす運用管理術を紹介 New! |

| ◆ | 上司や部下、部署内メンバーとの情報共有 を“ガラッ”と変えるコラボツールとは? New! |
| ◆ | おばかアプリ選手権、第4弾開催中!! ムダにカッコよくてくだらない作品求ム! |
| ◆ | 社内ファイルサーバを“クラウド”に統合 VPN直結「クラウド型ストレージ」を紹介 |

| ◆ | Twitterのアカウントはなぜ突破された? メールによる新手の攻撃手法とその対策 |
| ◆ | もう仮想化のお試しフェイズは終わりだ! Hyper-V 2.0が基幹システムも仮想化 |
| ◆ | 美人!? まあまあ? 気になる いやし系!! PV急増で「美人時計」がとった手段とは? |

| ◆ | クライアント企業から求められる人材 ⇒IT技術と経営戦略を併せ持つ「戦略家」 |
| ◆ | .NET編集長が実践する「技術情報検索術」 サンプル・コードを簡単に探す“技”は? |
| ◆ | 業務効率と情報セキュリティ対策を両立! 手間なく確実に機密情報を守る方法とは? |

| ◆ | 進化を続ける富士通ストレージETERNUS DX 製品開発者の自信を裏付けるものとは何か |
| ◆ | 運用管理の課題を“2つの観点”から分析 ユーザー満足度の高い「仮想環境」とは? |

| ◆ | 【CTC事例】約30の基幹システムを統合! 膨大なバッジジョブを制御した方法は? |
| ◆ | 仮想化すればコストは削減できるか? 仮想化に必要な「3つの視点」を解説する |
| ◆ | その数、なんと400台以上! グループ内 サーバの「統合管理」によるメリットは? |






