Dev Study
← Spring コース

21. パッケージはフォルダではなく名前

Java としては src/service でも動きます。 service; と書いて src/service に置いたは、 でも でもビルドと実行ができました。途中の jp/co/example は必須ではなく、が広く配布する向けに勧める慣習です。ただし はのパッケージの配下しか探さないので、全部の上に共通の根のパッケージが1つ要ります。

接頭辞が勧められる理由は、クラスの指し方にあります。Java のコードは、他のクラスを場所ではなく名前で指します。その名前がで、パッケージ名とクラス名を . でつないだものです。javac と はこの . を / に置き換えてファイルを探します。自分のクラスとライブラリは、(探しに行く場所の一覧)から探されます。jp や co はフォルダ分けではなく、この名前の一部です。

実行時には、自分のコードも全ライブラリも1つのクラスパスに並びます。同じ名前のクラスが2つあると、エラーも警告も出ず、先に並んだ方だけが使われました。は、この衝突を避けるための接頭辞です。Node は に場所を書き、ライブラリは node_modules という別の場所にあるので、アプリのソースに一意な名前を持ち込まずに済みます。この決め方の代償は次のレッスンで扱います。

点線の付いた語はタップすると説明が出ます。用語集を開く →

名前からファイルを探すまで(javac も JVM も同じ置き換えをする)
import jp.co.example.shop.order.OrderService;コードに書くのは名前(完全修飾名)。場所は書かない
. を / に置き換える
jp/co/example/shop/order/OrderService.class探すファイルの相対パス
クラスパスの先頭から順に、この相対パスを探す
自分のクラスtarget/classes など
ライブラリ A の JAR中も同じ階層
ライブラリ B の JAR中も同じ階層
最初に見つかった1つ
そのクラスを使う同じ名前が2つあっても、黙って先の方
だから名前が重ならない接頭辞が要る
  • 言語仕様(JLS 7.2)は、ディレクトリへの対応をファイルシステムに置く場合の単純な例として示しており、義務にはしていません。javac のマニュアルは、ソースの配置がパッケージの構成を写していることを期待すると書いています。
  • 名前をそのままファイル名にした com.example.demo.Hello.class という平らな置き方では、JVM はクラスを見つけられませんでした(JDK 25)。
  • src/service の構成は、JDK 25 の javac と Maven 3.9.16(ソースの場所を src に変える設定を3行足したもの)で各1回確かめました。Spring Boot は載せていない素の Java です。Boot のリファレンスは、package 宣言の無いクラスを避けることと、起動クラスを他のクラスより上のパッケージに置くことを勧めています。
  • 言語仕様(JLS 6.1)が一意な名前を求めているのは packages that are widely distributed で、付け方を suggested convention と呼んでいます。同じ段落に local and casual package names という語もあります。Maven の座標の groupId も同じ付け方に従います。
  • JDK 標準のクラス(String など)は、クラスパスから探されるのではありません。置き場所は JDK に入っている lib/modules で、下のコードの出力で jrt: と出るのがそれです。既定では、その多くが共有アーカイブ(CDS)から取り込まれます。親子に見えるパッケージの間にアクセス上の特別な関係はありません(JLS 7.1)。
  • JLS 7.1 は、パッケージ名の階層に意味が無いとは言い切っていません。同じ名前のクラスとサブパッケージを同居させられない、という1点を例外にしています。

▶ サンプルコードを実行してみよう(自由に書き換えてOK)

Java

図やコードに出てくる用語(タップで説明)

サンプルコードで身につける(5本) →

学んだ概念を、素朴な例から実務寄りの例まで5つの具体例で確認します。

公式ドキュメントで詳しく ↗