タイトル: パッケージ
SEOタイトル: Java パッケージ (package) 完全ガイド
| この記事の要点 |
|
package 宣言の基本
// File: com/example/myapp/User.java
package com.example.myapp;
import java.util.List;
import java.util.ArrayList;
public class User {
private String name;
public User(String name) { this.name = name; }
}
ルール:
package宣言はファイル先頭に 1 つだけ (コメント / 空行は OK)- パッケージ名は ディレクトリ構造と一致 必須
- 無宣言なら「デフォルトパッケージ」(本番では避ける)
- 慣習: 全小文字、逆ドメイン (
com.example)
ディレクトリ構造とパッケージ
src/
└── main/
└── java/
└── com/
└── example/
└── myapp/
├── User.java (package com.example.myapp;)
├── repository/
│ └── UserRepo.java (package com.example.myapp.repository;)
└── service/
└── UserSvc.java (package com.example.myapp.service;)
import の書き方
package com.example.myapp.service;
import com.example.myapp.User; // 単一クラス
import com.example.myapp.repository.UserRepo;
import java.util.List;
import java.util.Map;
// ワイルドカード (パッケージ直下のクラスのみ。サブパッケージは含まない)
import java.util.*; // List, Map, ArrayList, ... 全部
// → java.util.concurrent.* は別途必要
// 同名クラスは FQCN (Fully Qualified Class Name) で書く
import java.util.Date;
public class Sample {
Date a;
java.sql.Date b; // FQCN
}
public class UserSvc {
private final UserRepo repo;
private final List<User> cache = new ArrayList<>();
}
static import
import static java.lang.Math.PI;
import static java.lang.Math.sqrt;
import static java.util.Arrays.asList;
import static org.junit.jupiter.api.Assertions.*; // テストで定番
public class Calc {
double area(double r) {
return PI * r * r; // Math. が省略できる
}
double h(double a, double b) {
return sqrt(a * a + b * b);
}
}
class CalcTest {
void test() {
assertEquals(3.14, PI, 0.01);
assertTrue(true);
}
}
java.lang は自動 import
// 以下は import 不要
String s = "hello"; // java.lang.String
Integer i = 0; // java.lang.Integer
System.out.println(s); // java.lang.System
new Thread(() -> {}).start(); // java.lang.Thread
new RuntimeException(); // java.lang.RuntimeException
new Object(); // java.lang.Object
アクセス修飾子とパッケージ
| 修飾子 | 同クラス | 同パッケージ | サブクラス | 他パッケージ |
|---|---|---|---|---|
public | O | O | O | O |
protected | O | O | O | X |
| (なし) package private | O | O | X | X |
private | O | X | X | X |
package com.example.myapp.internal;
class InternalHelper { // package private (修飾子なし)
static String secret() { return "hidden"; }
}
// 同じパッケージ内なら見える
package com.example.myapp.internal;
class Other {
void m() {
InternalHelper.secret(); // OK
}
}
// 他パッケージからは見えない
package com.example.myapp.api;
import com.example.myapp.internal.InternalHelper; // ★ コンパイルエラー
Module System (Java 9+)
// src/main/java/module-info.java
module com.example.myapp {
// 自分が公開するパッケージ (これ以外は他モジュール from 不可視)
exports com.example.myapp.api;
exports com.example.myapp.dto;
// 内部用は公開しない
// (com.example.myapp.internal は exports しない)
// 必要な他モジュール
requires java.sql;
requires java.net.http;
requires com.fasterxml.jackson.databind;
// リフレクション許可
opens com.example.myapp.entity to org.hibernate.orm.core;
// サービス提供 / 利用
provides com.example.spi.MyService with com.example.myapp.MyServiceImpl;
uses com.example.spi.MyService;
}
命名規則とディレクトリ設計
| 層 | パッケージ名 | 含むもの |
|---|---|---|
| エントリポイント | com.example.myapp | Main / Application |
| コントローラ | ...myapp.controller or web | REST / View |
| サービス | ...myapp.service | ビジネスロジック |
| リポジトリ | ...myapp.repository | DB アクセス |
| エンティティ | ...myapp.entity or domain | JPA / モデル |
| DTO | ...myapp.dto | API 入出力 |
| 設定 | ...myapp.config | Spring Config 等 |
| 共通 | ...myapp.common / util | ユーティリティ |
| 内部 | ...myapp.internal | 非公開実装 |
Maven / Gradle でのパッケージ
<!-- pom.xml -->
<groupId>com.example</groupId>
<artifactId>myapp</artifactId>
<version>1.0.0</version>
<!-- → ソースは src/main/java/com/example/myapp/ -->// build.gradle
group = 'com.example'
version = '1.0.0'
// パッケージ名と group は揃えるのが慣例
// → 公開ライブラリでは Maven Central に登録できる
名前衝突を避けるコツ
- 逆ドメインを使う (
com.example)。所有していないドメインは避ける - OSS なら
io.github.usernameも慣例 (GitHub 所有を明示) - 機能ごとに分割 (
com.example.myapp.auth/...payment) - Java 標準 (
java.*) やjavax.*/jakarta.*と被らない
FAQ
Q: ワイルドカード import (import java.util.*) は使うべき?
A: 1 パッケージから 5 個以上使うなら可。ただし依存が見えにくくなるので明示派が主流。IDE が自動整理してくれる。
Q: パッケージ名と class 名を同じにできる?
A: 技術的には可だが混乱の元。慣習に従い com.example.user.UserService 等にする。
Q: Module System は必須?
A: 必須ではない。ライブラリを公開するなら推奨、アプリ内部だけなら無くても動く。Spring Boot は通常モジュール無し。