パッケージ (Java)

Javaパッケージ（）は名前空間の中にあるJavaクラスをまとめるメカニズムである。Javaパッケージは、JARファイルと呼ばれる圧縮ファイルの中に保存することができる。同じパッケージに属するクラス群を1つのグループとしてまとめたほうが、Javaクラスファイルを1つずつダウンロードするよりも高速化される。プログラマも一般に同じカテゴリに属しているクラスや類似した機能を提供するクラスをまとめたパッケージを使う。

Javaソースファイルは先頭に、そのソースファイル内で定義されるクラスが属するパッケージを指定する文を含むことができる。

 パッケージは、その配下に含む型に関してユニークな名前空間を提供する。
 同じパッケージにあるクラス群はお互いに保護された（protected）メンバー（メソッド、フィールド、ネストされた型）にアクセスできる。
 パッケージは次に述べる種類の型を含むことができる。
 クラス
 インタフェース
 列挙型
 アノテーション

特に、他の型の中に定義がネストされておらず、パッケージの直下に属するクラスやインタフェースを「トップレベルクラス」や「トップレベルインタフェース」と呼ぶ。トップレベルの型は、その型がと宣言されている場合にのみ、その型を含むパッケージの外部からアクセスできる。

役割としてはC++やC#などの言語に使われている名前空間（）に似ているが、その名前空間よりも機能は限定的であり、階層構造の概念はあるもののブロック構文を持たず、主に型名の衝突を避けるために存在する。またそのパッケージ内にある型は、アクセスレベル修飾子（）をデフォルトの無指定にすることでpackage-private設定となり、package-privateな型はパッケージ外部の型からのアクセスが禁止され、カプセル化による情報隠蔽を実現できる。これによりGoFデザインパターンの一つ、Facade パターンをより忠実に実現することができる。

 パッケージの使用 

Javaソースファイルでは、ファイルが所有する（ファイル内に書かれている）クラスまたはクラス群が属しているパッケージが、キーワードを使って指定される。
package java.awt.event;
あるパッケージが所有するクラスをJavaソースファイル内で使うには、宣言でパッケージからクラスをインポートするのが便利である。次の宣言はjava.awt.eventパッケージからすべてのクラスをインポートする。
import java.awt.event.*;
一方、次の宣言はパッケージからActionEventクラスだけをインポートする。
import java.awt.event.ActionEvent;
これらの宣言の後ではいずれも、以下のように単純クラス名を使ってActionEventクラスを参照することができる。
ActionEvent myEvent = new ActionEvent();
クラスの完全修飾名（）を使うことで、宣言なしでクラスを直接使うことができる。例えば、以下は先行する宣言を要求しない。
java.awt.event.ActionEvent myEvent = new java.awt.event.ActionEvent();

 パッケージアクセス保護 

あるパッケージ内のクラスは、アクセス修飾子を使って宣言されたクラスメンバーにアクセスできるのと同様に、「デフォルト」すなわちアクセス修飾子を無指定で宣言されたpackage-privateのクラスやメンバーにアクセスできる。クラスやメンバーが、、として宣言されていないとき、デフォルト（package-private）アクセスが強制される。それとは対照的に、他のパッケージ内にあるクラスはデフォルトアクセス宣言されたクラスやメンバーにアクセスできない。宣言されたクラスメンバーは、そのクラスのサブクラスである他のパッケージ内クラスからアクセスできるのと同様に、同じパッケージ内の（継承関係のない）クラスからもアクセスすることができる。

 JARファイル生成 

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 から追加されたアノテーション 
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の代替となるものである。

 Java SE 6のコアパッケージ 

 — 基本言語機能性と基本型basic language functionality and fundamental types — コレクションデータ構造クラス — 入出力操作 — 多倍長演算 — JavaによるNew I/Oフレームワーク — ネットワーク命令、ソケット、DNSルックアップ... — 暗号鍵生成、暗号化、復号 — データベースにアクセスするためのJava Database Connectivity (JDBC) — ネイティブGUIコンポーネントのパッケージの基本階層 — プラットフォーム非依存リッチGUIコンポーネントのパッケージ階層