Java道|クラスライブラリとパッケージの関係

Javaの便利なクラスは、役割ごとの巻物棚にきれいに整理されている。
クラスライブラリとパッケージの関係を理解すると、標準クラスを探しやすく、使いやすくなります。

Javaでは、自分でクラスを作るだけでなく、Javaが最初から用意してくれている便利なクラスも使えます。

たとえば、文字列を扱う String、計算に使う Math、入出力に使う BufferedReader、便利なデータ管理に使う ArrayList などです。

これらは、自分で一から作らなくても使える部品です。
このような、あらかじめ用意されたクラスの集まりを クラスライブラリ と呼びます。

鬼滅の刃風にたとえると、クラスライブラリは鬼殺隊本部に最初から用意されている巨大な巻物棚のようなものです。

そこには、隊士名簿、任務記録、通信の巻物、計算用のそろばん帳、日付管理の巻物、画像や画面表示の道具帳など、さまざまな用途の巻物がきちんと並んでいます。

ただし、これらの巻物が全部ひとつの棚に雑然と置かれているわけではありません。
Javaのクラスライブラリは、役割ごとに パッケージ で整理されています。

たとえば、基本的なクラスは java.lang、入出力関連は java.io、ネットワーク関連は java.net、便利な道具類は java.util というように分類されています。

Javaの考え方鬼滅の刃風のイメージ
クラスライブラリ鬼殺隊本部に用意された巨大な巻物棚
クラス1つひとつの巻物や道具
パッケージ用途ごとに分けられた棚
import別の棚の巻物を使うための案内札

これまで学んできた、package 文、import 文、パッケージ名.クラス名 という考え方は、自分で作ったクラスだけに関係するものではありません。

Javaが用意しているクラスライブラリを使うときにも、同じようにパッケージの考え方が使われます。

つまり、クラスライブラリを使いこなすには、
どのパッケージに、どんな役割のクラスが入っているのか
を意識することが大切です。

クラスライブラリとは何か

クラスライブラリとは、Javaがあらかじめ用意している便利なクラスの集まりです。

プログラムを書くとき、すべての機能を自分で作る必要はありません。

たとえば、文字列を扱う処理、ファイルを読む処理、日付を扱う処理、ネットワーク通信を行う処理などは、多くのプログラムで必要になります。

そのたびに全部を自作していたら、とても大変です。

そこでJavaには、よく使う機能がクラスとしてあらかじめ用意されています。

やりたいこと使われるクラスやパッケージの例
文字列を扱うString
数学的な計算をするMath
ファイルを読み書きするjava.io
日付や便利な道具を使うjava.util
ネットワーク通信をするjava.net
大きな数値を正確に扱うjava.math

鬼滅の刃風にたとえると、自分で毎回刀や地図や通信札を作るのではなく、本部に用意された道具を借りて任務に使うようなものです。

Javaのクラスライブラリを使うことで、プログラムを効率よく作れるようになります。

クラスライブラリのクラスもパッケージで整理されている

クラスライブラリには、非常に多くのクラスがあります。

もしそれらが全部同じ場所に置かれていたら、必要なクラスを探すだけでも大変です。

そこでJavaでは、標準クラスライブラリのクラスも、用途ごとにパッケージへ分類されています。

パッケージ名主な役割
java.langJavaの基本的なクラス
java.io入出力関連のクラス
java.netネットワーク関連のクラス
java.util便利な補助機能やコレクション関連のクラス
java.math高精度な数値計算に関するクラス
java.text数値や日付などの表示形式、国際化関連のクラス
java.awtウィンドウ部品関連のクラス
java.awt.eventイベント処理関連のクラス
java.awt.image画像処理関連のクラス

このように、パッケージ名を見るだけでも、だいたいどんな役割のクラスが含まれているのかが分かります。

鬼滅の刃風に言えば、鬼殺隊本部の巻物棚が、次のように分類されているイメージです。

Javaのパッケージ鬼滅の刃風の棚
java.lang基本任務に必ず使う共通巻物棚
java.io記録の読み書き用の巻物棚
java.net遠方連絡や通信の巻物棚
java.util任務を助ける便利道具の棚
java.math精密な計算を行う算術棚
java.awt画面や表示部品の道具棚
java.awt.event操作や反応を扱う巻物棚
java.awt.image画像を扱う巻物棚

パッケージは、ただクラスを入れる入れ物ではありません。
クラスの役割を整理し、必要な機能を探しやすくするための大切なしくみです。

パッケージで整理されていると何が便利なのか

クラスライブラリがパッケージで整理されていると、必要なクラスを探しやすくなります。

たとえば、ファイルの読み書きをしたいなら java.io を見ればよい、と考えられます。
便利なリストや日付関連の機能を使いたいなら java.util を見る、というように目的別に探せます。

状態困ること・便利なこと
パッケージ整理がない場合すべてのクラスが同じ場所に集まり、探しにくい
パッケージ整理がある場合用途ごとに分かれているため、目的のクラスを探しやすい

さらに、パッケージは同じ名前のクラスを区別するためにも役立ちます。

たとえば、同じ名前のクラスが複数あっても、パッケージが違えば別のクラスとして扱えます。

指定意味
pa.DemonSlayerpa パッケージの DemonSlayer
pc.DemonSlayerpc パッケージの DemonSlayer
java.awt.Listjava.awt パッケージの List
java.util.Listjava.util パッケージの List

鬼滅の刃風にたとえると、同じ名前の巻物があっても、置かれている棚が違えば取り違えを防げます。

名前だけを見るのではなく、どの棚にあるのかまで含めて管理する。
これがパッケージの大きな役割です。

クラスライブラリを使うときもimportが基本

別パッケージのクラスを使うときは、import を使うのが基本です。

これは、自分で作ったクラスを使う場合だけでなく、Javaのクラスライブラリを使う場合も同じです。

たとえば、java.io パッケージにある BufferedReader クラスを使いたいとします。

その場合、ソースファイルの先頭付近に次のように書きます。

import java.io.BufferedReader;

これにより、プログラムの中では BufferedReader と短く書けます。

import を使わない場合は、次のように完全な名前で書く必要があります。

java.io.BufferedReader

比較すると、次のようになります。

書き方特徴
java.io.BufferedReaderどのパッケージのクラスか明確だが長い
import java.io.BufferedReader; を書いて BufferedReader短く書けて読みやすい

鬼滅の刃風にたとえると、毎回 java.io の棚にある BufferedReader の巻物 と言うのは長いです。

そこで、任務開始前に import java.io.BufferedReader; と案内札を出しておきます。
そうすれば、任務中は BufferedReader と短く呼べるようになります。

なぜimportが必要になるのか

Javaのクラスライブラリには、多くのクラスがあります。

それらはパッケージごとに分類されているため、別パッケージのクラスを使うときには、どこにあるクラスなのかをJavaに伝える必要があります。

BufferedReader は java.io パッケージにあります。

そのため、何も準備しない場合は、次のように完全な名前で指定する必要があります。

java.io.BufferedReader

しかし、何度もこの形を書くと、コードが長くなりやすいです。

そこで import を使います。

import java.io.BufferedReader;

これを書いておけば、以降は BufferedReader と短く書けます。

考え方内容
パッケージ名.クラス名クラスの完全な住所を示す
importそのクラスを短い名前で使えるようにする
クラス名だけimport 後に使いやすくなる短い表記

import は、クラスの所属を変えるものではありません。

BufferedReader は、import しても java.io パッケージのクラスのままです。
import は、あくまで今書いているファイルの中で使いやすくするための宣言です。

java.langだけは特別

ここで大切な例外があります。

それが java.lang パッケージ です。

java.lang に含まれるクラスは、通常 import を書かなくても使えます。

たとえば、String や Math は、これまで特別な import を書かずに使ってきたはずです。

String name = "水月";

int max = Math.max(10, 20);

本来、String は java.lang.String、Math は java.lang.Math です。

しかし、java.lang はJavaの基本的なクラスを含む特別なパッケージなので、自動的に使えるようになっています。

クラス本来の完全名import
Stringjava.lang.String通常不要
Mathjava.lang.Math通常不要
Systemjava.lang.System通常不要

この点を整理すると、次のようになります。

パッケージimport の必要性
java.lang通常不要
java.lang 以外基本的に必要

鬼滅の刃風にたとえると、java.lang は鬼殺隊士なら誰でも常に携帯している基本道具のようなものです。

任務のたびに申請しなくても、最初から使える状態になっています。

String を import なしで使えるのは、String が特別な文法だからではありません。
String が java.lang に属しており、java.lang が自動的に使えるパッケージだからです。

同じパッケージの複数クラスをimportするとき

同じパッケージから複数のクラスを使いたい場合、1つずつ import することもできます。

たとえば、java.io の BufferedReader と IOException を使う場合です。

import java.io.BufferedReader;
import java.io.IOException;

この書き方は正しいです。

使うクラスが少ない場合は、どのクラスを使っているのかが明確で分かりやすいです。

import 文意味
import java.io.BufferedReader;BufferedReader を使う
import java.io.IOException;IOException を使う

ただし、同じパッケージからたくさんのクラスを使う場合、import 文が何行も並びます。

鬼滅の刃風にたとえると、java.io の棚から複数の巻物を使いたいのに、1本ずつ申請書を書いているようなものです。

そのようなときに便利なのが、アスタリスクを使った import です。

アスタリスクを使ったimport

同じパッケージの複数クラスをまとめて使いたい場合は、アスタリスクを使えます。

import java.io.*;

このように書くと、java.io パッケージに含まれるクラスを使いやすくなります。

書き方意味
import java.io.BufferedReader;BufferedReader だけを指定する
import java.io.IOException;IOException だけを指定する
import java.io.*;java.io パッケージ内のクラスをまとめて使いやすくする

アスタリスクを使うと、同じパッケージのクラスを複数使うときに、import 文を短くできます。

ただし、アスタリスクは何でもまとめて読み込む魔法ではありません。

重要なのは、指定したパッケージの直下のクラスだけが対象 という点です。

アスタリスクではサブパッケージまで含まれない

ここはとても大切です。

import java.awt.*; と書いた場合、使いやすくなるのは java.awt パッケージに含まれるクラスです。

しかし、java.awt.image パッケージのクラスまでは含まれません。

import java.awt.*;

この書き方では、java.awt.image のクラスは対象外です。

java.awt.image のクラスも使いたい場合は、別に次のような import が必要です。

import java.awt.image.*;

表で整理すると、次のようになります。

import 文利用しやすくなる範囲
import java.awt.*;java.awt パッケージのクラス
import java.awt.image.*;java.awt.image パッケージのクラス
import java.awt.*; だけjava.awt.image までは含まれない

これは、サブパッケージが別パッケージとして扱われるからです。

以前学んだ pa と pa.sub の関係と同じです。

パッケージJavaでの扱い
papa パッケージ
pa.subpa.sub パッケージ
java.awtjava.awt パッケージ
java.awt.imagejava.awt.image パッケージ

名前がつながっていても、Javaでは別々のパッケージです。

鬼滅の刃風にたとえると、java.awt の棚をまとめて使う申請をしても、その中の別管理区画である java.awt.image の棚までは自動では使えない、ということです。

クラスライブラリのパッケージを鬼滅の刃風に整理する

Javaのクラスライブラリを、鬼滅の刃風の本部資料棚として見ると、次のように整理できます。

パッケージ鬼殺隊本部の棚のイメージ使う場面
java.lang基本道具棚String、Math、System など基本機能
java.io記録入出力棚ファイルや文字の読み書き
java.net遠方通信棚ネットワーク通信
java.util便利道具棚リスト、日付、補助機能
java.math精密計算棚大きな数値や正確な計算
java.text表示形式棚日付や数値の表示調整
java.awt画面部品棚ウィンドウや部品
java.awt.event操作反応棚ボタン操作やイベント
java.awt.image画像処理棚画像関連の処理

こうして見ると、Javaの標準クラスライブラリは、ただ大量のクラスが集まっているだけではないことが分かります。

用途ごとに棚が分かれているため、必要な機能を探しやすくなっています。

図:クラスライブラリはパッケージで整理されている

↓クリックすると拡大表示されます。

この図が示していること

この図では、Javaのクラスライブラリが、用途ごとのパッケージで整理されている様子を表しています。

中央の Java クラスライブラリ は、Javaが最初から用意している便利なクラスの集まりです。

その中には、java.lang、java.io、java.net、java.util、java.math、java.awt などの棚があります。

パッケージ役割
java.lang基本的なクラス
java.io入出力関連
java.netネットワーク関連
java.util便利機能関連
java.math数値計算関連
java.awt画面部品関連

この図から分かることは、クラスライブラリはただ大量のクラスを集めたものではなく、用途ごとにパッケージで整理されているということです。

図:importとアスタリスクの範囲

↓クリックすると拡大表示されます。

この図が示していること

この図では、アスタリスクを使った import の範囲を表しています。

左側の java.awt には、Button、Frame、Graphics などのクラスがあります。
import java.awt.*; と書くと、java.awt パッケージ内のクラスを使いやすくできます。

一方、右側の java.awt.image は、java.awt の下に見える名前ですが、Javaでは別パッケージとして扱われます。

そのため、java.awt.image のクラスを使いたい場合は、別に import java.awt.image.*; が必要です。

import 文対象
import java.awt.*;java.awt のクラス
import java.awt.image.*;java.awt.image のクラス
import java.awt.*; だけjava.awt.image は含まれない

この図から分かることは、アスタリスクは指定したパッケージ直下のクラスだけを対象にし、サブパッケージまでは含まないということです。

モジュールという上位の考え方

Java 9 以降では、パッケージよりさらに大きな単位として モジュール という考え方があります。

パッケージは、クラスを整理する単位です。
一方、モジュールは、パッケージのまとまりをさらに管理する単位です。

単位役割
クラス実際の処理を持つ部品
パッケージクラスを用途ごとに整理する単位
モジュールパッケージ群の公開範囲や依存関係を管理する単位

鬼滅の刃風にたとえると、クラスは1本の巻物です。
パッケージは巻物を整理する棚です。
モジュールは、複数の棚をまとめた部署や管理区画です。

たとえば、ある部署では、外部に見せてよい棚と、内部だけで使う棚を分けたいことがあります。

モジュールを使うと、次のようなことを管理できます。

モジュールで考えること内容
どのパッケージを外部に公開するか使ってよい機能を明確にする
どのパッケージを内部だけで使うか内部処理を隠す
どのモジュールがどのモジュールを使うか依存関係を整理する

モジュールを定義するときは、module-info.java というファイルを使います。

ただし、Java学習の初期段階では、まずパッケージと import をしっかり理解することが大切です。

モジュールは、より大きな構成を扱うときに登場する上位の整理単位だと考えるとよいです。

標準クラスライブラリとモジュール

Java 9 以降では、標準クラスライブラリもモジュール単位で整理されています。

たとえば、基本的なクラス群は java.base というモジュールに含まれています。

java.base には、java.lang など、Javaの基本的な機能が含まれます。

モジュール含まれるものの例
java.baseJavaの基本的な機能
java.desktopAWTやSwingなど、画面関連の機能
java.sqlデータベース関連の機能

普段の学習では、モジュール名を強く意識しなくても使える場面が多いです。

しかし、大きなアプリケーションやライブラリを扱うようになると、どのモジュールが必要なのかを指定する場面があります。

鬼滅の刃風に言うと、最初は本部の巻物棚を使うだけで十分です。
しかし、大きな任務部隊を組むようになると、どの部署の棚を外部に公開するか、どの部署がどの部署を利用するかまで管理する必要が出てくる、というイメージです。

名前のないモジュール

モジュールを明示していない通常の学習用プログラムは、名前のないモジュールに属するものとして扱われます。

つまり、最初から module-info.java を書かなくても、Javaの学習や小さなプログラムの実行はできます。

状態扱い
module-info.java がない名前のないモジュールに属する
module-info.java がある名前のあるモジュールとして扱う

この仕組みがあるため、初心者の段階では、モジュールを強く意識しなくてもJavaを学べます。

まずは、クラス、パッケージ、import の関係を理解する。
その上で、必要になったらモジュールという上位のしくみに進む、という流れで十分です。

クラスライブラリを使いこなすために大切な視点

Javaの学習では、自分でクラスを作れるようになることも大切です。

しかし、それと同じくらい大切なのが、Javaが用意しているクラスライブラリを上手に使うことです。

そのためには、どのパッケージに何があるのかを意識できるようになる必要があります。

やりたいこと見るとよいパッケージ
基本的なクラスを使うjava.lang
ファイルや文字を読み書きするjava.io
ネットワークを扱うjava.net
リストや便利な補助機能を使うjava.util
正確な数値計算をするjava.math
表示形式を整えるjava.text
画面部品を扱うjava.awt
イベントを扱うjava.awt.event
画像を扱うjava.awt.image

この視点があると、必要なクラスを探しやすくなります。

また、import の意味が分かっていれば、別パッケージのクラスも自然に使えるようになります。

クラスライブラリとパッケージで押さえておきたいこと

大切なポイント内容
クラスライブラリJavaがあらかじめ用意しているクラスの集まり
パッケージクラスを役割ごとに整理するしくみ
標準クラスもパッケージで整理されるjava.lang、java.io、java.util など
import別パッケージのクラスを短く使いやすくする
java.lang通常 import 不要
import パッケージ名.*;同じパッケージ直下の複数クラスを使いやすくする
サブパッケージ* では自動的に含まれない
モジュールパッケージ群をさらに大きく管理する単位

Javaのクラスライブラリは、ただ便利なクラスがたくさん置かれているだけではありません。

役割ごとにパッケージへ整理され、必要に応じて import して使えるようになっています。

鬼滅の刃風に言えば、Javaの標準クラスライブラリは、任務に必要な巻物や道具が分類された巨大な本部資料庫です。

どの棚にどんな巻物があるのかを知り、必要なものを import して使えるようになると、Javaの便利な機能をもっと自然に使いこなせるようになります。