パッケージ (Java)

Javaパッケージ（Java package）は名前空間の中にあるJavaクラスをまとめるメカニズムである。Javaパッケージは、JARファイルと呼ばれる圧縮ファイルの中に保存することができる。同じパッケージに属するクラス群を1つのグループとしてまとめたほうが、Javaクラスファイルを1つずつダウンロードするよりも高速化される。プログラマも一般に同じカテゴリに属しているクラスや類似した機能を提供するクラスをまとめたパッケージを使う。 Javaソースファイルは先頭に、そのソースファイル内で定義されるクラスが属するパッケージを指定するpackage文を含むことができる。 パッケージは、その配下に含む型に関してユニークな名前空間を提供する。 同じパッケージにあるクラス群はお互いに保護された（protected）メンバー（メソッド、フィールド、ネストされた型）にアクセスできる。 パッケージは次に述べる種類の型を含むことができる。 クラス インタフェース 列挙型 アノテーション 特に、他の型の中に定義がネストされておらず、パッケージの直下に属するクラスやインタフェースを「トップレベルクラス」や「トップレベルインタフェース」と呼ぶ。トップレベルの型は、その型がpublicと宣言されている場合にのみ、その型を含むパッケージの外部からアクセスできる。 役割としてはC++やC#などの言語に使われている名前空間（英: namespace）に似ているが、その名前空間よりも機能は限定的であり、階層構造の概念はあるもののブロック構文を持たず、主に型名の衝突を避けるために存在する。またそのパッケージ内にある型は、アクセスレベル修飾子（access level modifiers）をデフォルトの無指定にすることでpackage-private設定となり、package-privateな型はパッケージ外部の型からのアクセスが禁止され、カプセル化による情報隠蔽を実現できる。これによりGoFデザインパターンの一つ、Facade パターンをより忠実に実現することができる。 Javaソースファイルでは、ファイルが所有する（ファイル内に書かれている）クラスまたはクラス群が属しているパッケージが、packageキーワードを使って指定される。 package java.awt.event; あるパッケージが所有するクラスをJavaソースファイル内で使うには、import宣言でパッケージからクラスをインポートするのが便利である。次の宣言はjava.awt.eventパッケージからすべてのクラスをインポートする。 import java.awt.event.*; 一方、次の宣言はパッケージからActionEventクラスだけをインポートする。 import java.awt.event.ActionEvent; これらのimport宣言の後ではいずれも、以下のように単純クラス名を使ってActionEventクラスを参照することができる。 ActionEvent myEvent = new ActionEvent(); クラスの完全修飾名（fully qualified name）を使うことで、import宣言なしでクラスを直接使うことができる。例えば、以下は先行するimport宣言を要求しない。 java.awt.event.ActionEvent myEvent = new java.awt.event.ActionEvent(); あるパッケージ内のクラスは、protectedアクセス修飾子を使って宣言されたクラスメンバーにアクセスできるのと同様に、「デフォルト」すなわちアクセス修飾子を無指定で宣言されたpackage-privateのクラスやメンバーにアクセスできる。クラスやメンバーがpublic、protected、privateとして宣言されていないとき、デフォルト（package-private）アクセスが強制される。それとは対照的に、他のパッケージ内にあるクラスはデフォルトアクセス宣言されたクラスやメンバーにアクセスできない。protected宣言されたクラスメンバーは、そのクラスのサブクラスである他のパッケージ内クラスからアクセスできるのと同様に、同じパッケージ内の（継承関係のない）クラスからもアクセスすることができる。 JARファイルはjarコマンドラインユーティリティによって生成される。次のコマンドは拡張子.classを持つすべてのファイルをJARファイルmyPackage.jarに圧縮する。 jar cf myPackage.jar *.class コマンドラインオプション'c'はjarコマンドに「アーカイブの新規作成」を指示する。'f'オプションはファイルの作成を指示する。ファイル名はその次に来て、JARファイルのコンテンツ（内容物）の前に指定される。 パッケージは通常、ピリオド(.) （「ドット」と発音）によって分割された階層レベルで階層命名パターンを使用する。名前階層が下位であるパッケージはしばしば上位層に相当するパッケージの「サブパッケージ」と呼ばれるが、パッケージ間には意味的な関係は無い。Java Language Specification は二つの公開されたパッケージが同じ名前を持つことを避けるためにパッケージ命名規約を設けている。命名規約がユニークなパッケージ名を作成する方法を説明するように、広く配布されたパッケージはユニークな名前空間を持つだろう。これはパッケージ群が簡単で無意識的にインストールされカタログ化されるようにしている。 パッケージ名は組織のトップレベルドメイン名と、そのときの組織のドメインといくつかのサブドメインリストが逆順になったもので始まることが推奨されている。組織はそれらの名前にそのときに特定の名前を選ぶ。パッケージ名は可能ならばすべて小文字にすべきである。 例えば、もしカナダにMySoftと呼ばれる組織がfraction(小数、分数)を扱うパッケージを作るとすると、パッケージをca.mysoft.fractionsとネーミングすることは、他社によって開発された類似するもうひとつのパッケージからfractionパッケージを見分ける。もしMySoftと呼ばれるアメリカの企業もまたfractionパッケージを作るとするが、名前はcom.mysoft.fractionsであり、そのとき、それら二つのパッケージにあるクラスはユニークに定義され、名前空間は分割される。 曖昧でないパッケージ名に関して完全な規約と、パッケージ名に直接使うことができないインターネットドメイン名をパッケージに命名するルールは、Java言語仕様のChapter 6.1で説明されている。 ハイフン(-)が使われているドメイン名をそのままJavaソースコードで使用するとコンパイルエラーを引き起こす。そのためハイフンが使われているドメイン名には、ハイフンの代わりにアンダースコア (_)を使用する。 Java SE 5から追加されたアノテーションは、パッケージも対象にすることができる。 パッケージにアノテーションを保存するには、該当するパッケージディレクトリにpackage-info.javaというファイルを作り、以下のように記述する。 /** * パッケージの説明。 * パッケージのコメントにはJavadocのタグがそのまま使える。 */ @Deprecated package com.example.wikipedia; この例は、パッケージcom.example.wikipediaを非推奨にしていることを意味する。このpackage-info.javaはJavaコンパイラに警告を表示させる以外に、Javadocにパッケージの説明を表示するドキュメントを生成させるためにも利用される。package-info.javaは、パッケージにアノテーションを付加するために作られ、従来のpackage.htmlの代替となるものである。 ^ Chapter 8. Classes | Java SE 8 Language Specification | Oracle ^ Chapter 9. Interfaces | Java SE 8 Language Specification | Oracle ^ Chapter 7. Packages | Java SE 8 Language Specification | Oracle ^ a b Controlling Access to Members of a Class (The Java™ Tutorials > Learning the Java Language > Classes and Objects) JAR (ファイルフォーマット) クラスパス Apache Harmony Java SE 9 API Javadocs Java Language Specification, 3rd edition: Unique Package Names Java Package Naming Conventions ウィキブックスにJava関連の解説書・教科書があります。