Javaのアクセス修飾子は、クラスやフィールド、メソッドを「どこから使えるか」を決めるキーワードです。public・protected・default(修飾子なし)・privateの4種類があります。
迷ったときは、狭いほうから選ぶのが基本です。フィールドはprivateにし、外から呼ばせたいメソッドだけpublicにします。protectedとdefaultは、継承先や同じパッケージの中だけで使わせたい場面に絞って使います。
私も学び始めのころは、publicやprivateを意味を考えずに「おまじない」のように書いていました。この記事では、4種類の違いをアクセス範囲の表とコード例で確かめ、実務でよくある選び方の失敗まで説明します。
アクセス修飾子とは?Javaにおける基本概念を理解しよう

Javaにおけるアクセス修飾子とは、クラスやフィールド、メソッドへのアクセスをどこから許可するかを制御するためのキーワードです。
文字通り、アクセスを「修飾」し、制限をかける役割を持っています。
アクセス修飾子の役割と必要性
アクセス修飾子の最も重要な役割は、プログラムの安全性を高めることです。
もし、どこからでも自由にクラスの内部データにアクセスできてしまうと、意図しない場所で値が書き換えられ、予期せぬバグやエラーの原因になります。
たとえば、銀行口座の残高を管理するプログラムを考えてみましょう。残高という重要なデータを誰でも直接変更できたら、システムは成り立ちません。
「入金」や「出金」といった決められた手続き(メソッド)を通してのみ操作できるように制限する必要があります。
アクセス修飾子は、外部から勝手に触られたくない重要なデータを守り、決められたルールで安全にプログラムを動かすための仕組みなのです。
Javaのアクセス修飾子一覧(4種類)
Javaには、アクセスの制限範囲が異なる4種類のアクセス修飾子が存在します。
これらのアクセス修飾子は、制限が緩いものから厳しいものへと段階的に設定されており、状況に応じて使い分けることが重要です。
カプセル化とアクセス修飾子の関係
カプセル化は、オブジェクト指向プログラミングにおける重要な概念の一つです。
これは、クラスの内部データ(フィールド)と、そのデータを操作する手続き(メソッド)を一つにまとめ、内部の詳細を外部から隠蔽する考え方を指します。
このカプセル化を実現するために、アクセス修飾子が活躍します。具体的には、フィールドをprivateにして外部から直接アクセスできないように隠蔽します。
そのうえで、そのフィールドを操作するためのpublicなメソッド(ゲッターやセッター)を公開します。
これにより、クラスの利用者は内部構造を意識することなく、公開されたメソッドを通じて安全にデータを操作できます。
カプセル化は、プログラムの独立性を高め、仕様変更に強い、保守性の高いコードを作成するための基本原則です。
Javaのアクセス修飾子の種類と違い

ここでは、4種類のアクセス修飾子が持つアクセス制限の範囲と、それぞれの違いについて詳しく見ていきましょう。
public(パブリック)|どこからでもアクセス可能
publicは、最もアクセス制限が緩い修飾子です。
publicが付けられたクラス、フィールド、メソッドは、プロジェクト内のどのクラスからでもアクセスできます(モジュール(module-info.java)を使う場合は、そのパッケージがexportsされている必要があります)。
ライブラリとして提供されるクラスや、プログラムの主要なエントリーポイントとなるメソッドなど、外部に公開して自由に使ってもらいたい機能に対して使用します。
APIとして機能する部分と考えると分かりやすいでしょう。
protected|継承先からアクセス可能
protectedは少し特殊なアクセス修飾子です。
同一パッケージ内のクラス、または別パッケージであってもそのクラスを継承したサブクラスからアクセスが可能です。ただし、別パッケージのサブクラスからアクセスできるのは、サブクラス自身(thisやサブクラス型の変数)を通した場合に限られます。親クラス型の変数(例: Animal a = new Animal(); a.protectedSound)を通したアクセスはコンパイルエラーになります。
この特性から、主に継承関係にあるクラス間で、特定の情報や機能を共有したい場合に使われます。
フレームワークやライブラリなどで、拡張性を考慮した設計を行う際によく見られます。
default|同一パッケージのみアクセス可能
defaultは、クラスのフィールドやメソッドなどでアクセス修飾子を何も記述しなかった場合に適用されるアクセスレベルです。ただし、インターフェースのメンバーは何も書かなくても暗黙的にpublicになります。
package-private(パッケージプライベート)とも呼ばれます。
defaultのメンバーは、同じパッケージに所属するクラスからのみアクセス可能です。
パッケージというまとまりの中でだけ利用される補助的なクラスや、内部的な処理で利用するメソッドなどに適しています。
パッケージの外に公開する必要はないが、パッケージ内では共有したい、という場面で有効です。
private(プライベート)|クラス内のみアクセス可能
privateは、最もアクセス制限が厳しい修飾子です。
privateが付けられたメンバーは、そのメンバーが定義されているクラスの内部からしかアクセスできません。
クラスの外部に公開する必要のない、内部的な状態を保持するフィールドや、そのクラス内だけで使われる補助的なメソッドに使用します。
前述したカプセル化の原則に従い、フィールドは原則としてprivateにするのがJavaプログラミングの基本です。
これにより、クラスの安全性が大幅に向上します。
アクセス修飾子の使い分け方と実例

理論を学んだところで、次に実際のプログラミングでどのようにアクセス修飾子を使い分ければよいのか、具体的な例を挙げて解説します。
クラスとメソッドでのアクセス修飾子の使い方
トップレベルのクラスに付けられるアクセス修飾子はpublicかdefaultの2種類です(privateやprotectedを付けるとコンパイルエラーになります)。なお、クラスの中に定義する内部クラス(ネストしたクラス)には、メンバーとして4種類すべてを付けられます。
publicクラス: パッケージの外部に公開し、誰でも利用できるようにしたいクラスに使います。ほとんどの主要なクラスはpublicで定義されます。defaultクラス: 同じパッケージ内でのみ利用される、補助的なクラスに使います。そのパッケージの機能を実装するための「部品」のようなイメージです。
メソッドのアクセス修飾子は、そのメソッドの役割によって決まります。
publicメソッド: 外部に公開する操作(API)です。例えば、オブジェクトの状態を取得するゲッターや、状態を設定するセッターなどが該当します。privateメソッド: クラス内部の複雑な処理を分割するためのヘルパーメソッドなど、外部に公開する必要がない処理に使われます。リファクタリングの際に、長大なpublicメソッドを複数のprivateメソッドに分割することはよくあります。
フィールドへの修飾子の付け方の注意点
繰り返しになりますが、フィールド(インスタンス変数)には原則としてprivate修飾子を付けます。これは、カプセル化(情報隠蔽)の原則を守るためです。
もしフィールドをpublicにしてしまうと、どこからでも値を直接書き換えられるようになり、オブジェクトの状態が予期せぬ形で変更されてしまう危険性があります。
値の取得や設定が必要な場合は、publicなゲッターメソッドやセッターメソッドを用意しましょう。
セッターメソッド内で値の妥当性チェック(例えば、年齢に負の値が設定されないようにするなど)を実装することで、オブジェクトの状態を常に正しく保てます。
コンストラクタのアクセス修飾子
コンストラクタにもアクセス修飾子を付けられます。
通常はpublicにして外部から自由にインスタンス化できるようにしますが、privateにすると外部からのnewを禁止できます。
この特性は、インスタンスを1つだけに制限する「シングルトンパターン」を実現する手段の1つとして使われます。
コンストラクタをprivateにし、代わりにクラス内のstaticメソッドを通してインスタンスを取得させることで、外部からの無秩序なインスタンス生成を防げます。
アクセス修飾子を使い分けるときの判断基準
どのアクセス修飾子を選べばよいか迷ったときは、「可能な限りアクセス範囲を狭くする」という原則に立ち返りましょう。これを最小権限の原則と呼びます。
- 最初に
privateで定義できないか検討する。 - 同一パッケージ内の他クラスからのアクセスが必要な場合は
defaultにする。 - 継承したサブクラスに公開する必要がある場合は
protectedにする。 - 上記以外で、どうしても外部に公開する必要がある場合にのみ
publicを選択する。
この思考プロセスを習慣づけることで、自然と堅牢で安全なクラス設計ができるようになります。
アクセス修飾子を理解するためのコード例

ここでは、具体的なコードを見ながらアクセス修飾子の動作を確認していきましょう。
public/privateの組み合わせ例
ゲッター/セッターは、publicとprivateの役割を理解するための最も典型的な例です。
このコードでは、nameとageフィールドをprivateにすることで、直接のアクセスを防いでいます。
年齢ageに負の値のような不正なデータがセットされないよう、setAgeメソッド内でチェック処理を入れている点がポイントです。
protected/defaultの比較例
protectedとdefaultの違いは、パッケージをまたいだ継承関係で顕著になります。
パッケージ1: com.example.animal
パッケージ2: com.example.main
DogクラスはAnimalクラスを継承しています。
別パッケージにありますが、サブクラスなのでprotectedなprotectedSoundフィールドにアクセスできます。
一方、defaultのdefaultNameフィールドにはアクセスできず、コンパイルエラーが発生します。
アクセス制限エラーの原因と対処法
Javaでプログラミングをしていると、以下のようなコンパイルエラーに遭遇することがあります。
The field [フィールド名] is not visible(Eclipseの表示)
[メンバー名] has private access in [クラス名](javacの表示。defaultのメンバーに別パッケージからアクセスした場合は「[メンバー名] is not public in [クラス名]; cannot be accessed from outside package」、protectedのメンバーに別パッケージの無関係なクラスからアクセスした場合は「[メンバー名] has protected access in [クラス名]」と表示されます)
これらのエラーは、アクセスが許可されていないメンバー(フィールドやメソッド)にアクセスしようとしたときに発生します。
原因:
アクセスしようとしているメンバーのアクセス修飾子によって、アクセスが制限されている。
対処法:
- 設計を見直す: なぜそのメンバーにアクセスする必要があるのかを考えます。
privateなメンバーに直接アクセスしようとしている場合、それはクラスの設計思想に反している可能性があります。代わりに用意されているpublicなメソッドを使うべきではないか検討しましょう。 - アクセス修飾子を変更する: 設計上、どうしてもアクセスが必要な場合は、アクセス修飾子をより緩いもの(例:
private->defaultやpublic)に変更します。ただし、これは安易に行うべきではなく、なぜそのアクセスレベルが必要なのかを明確に説明できる場合に限ります。
アクセス修飾子を正しく使うためのベストプラクティス

最後に、アクセス修飾子を効果的に活用し、より質の高いコードを書くためのベストプラクティスを紹介します。
最小限のアクセス権にする原則(情報隠蔽の重要性)
繰り返し強調しますが、常に最小限のアクセス権を付与することを心がけてください。
これは「情報隠蔽」や「最小権限の原則」として知られる、オブジェクト指向設計の基本中の基本です。
- 変更の影響範囲を限定できる: 内部実装を
privateで隠蔽しておけば、将来その実装方法を変更しても、クラスの外部(利用者側)に影響が及びません。 - クラスの利用者が迷わない:
publicなメソッドだけを見れば、そのクラスの使い方が分かります。内部の複雑な実装を気にする必要がなくなり、利用しやすさが向上します。 - バグの混入を防ぐ: 意図しない使われ方を防ぎ、オブジェクトの状態を健全に保つことで、デバッグが容易で安定したプログラムになります。
チーム開発でのアクセス修飾子の設計ルール
チームで開発を行う場合、アクセス修飾子の使い方は、個人の裁量だけでなく、チームとしてのコーディング規約で定めることが望ましいです。
- APIとして公開する範囲を明確にする: どのクラスやメソッドを
publicにするか(つまり、チーム内の他のメンバーが使ってよい機能か)を設計段階で合意します。 - パッケージの設計: 関連性の高いクラスを同じパッケージにまとめ、
defaultアクセス修飾子を有効に活用することで、パッケージ内での連携を密にしつつ、パッケージ外への不要な情報流出を防げます。
明確なルールを設けることで、コードの意図が伝わりやすくなり、開発効率とメンテナンス性が向上します。
よくある誤用パターンとその修正例
誤用パターン1: とりあえず全部publicにしてしまう
初心者によく見られるパターンです。
アクセスエラーが出るたびにpublicに変更していくと、最終的にすべてのメンバーがpublicになってしまい、カプセル化が完全に崩壊します。
- 修正例: フィールドは原則として
privateにします。メソッドもまずはprivateで考え、外部に公開する必要があるものだけをpublicに変更していく、という手順を踏みましょう。
実際に、銀行口座系のドメインでpublicフィールドを使っていたコードを引き継いだことがあります。
すると、別チームのメンバーが残高フィールドを直接書き換えるコードを書いていました。
フィールドをprivateにしてゲッター・セッターに統一したところ、同種のバグは0件になりました。
冒頭で触れた「銀行口座の残高」という例は、決して大げさな仮定ではありません。
誤用パターン2: protectedの乱用
継承が便利だからといって、安易にprotectedを使うべきではありません。
protectedはクラス間の結合度を強め、サブクラスが親クラスの実装に強く依存してしまう原因になります。
- 修正例: 継承は強力ですが、結合度が高い諸刃の剣です。本当に継承が必要な設計なのか、委譲(コンポジション)で代替できないかを検討しましょう。
protectedは、フレームワークのように拡張を前提とした設計など、明確な意図がある場合に限定して使用するのが賢明です。
finalとの組み合わせで継承・変更を禁止する
アクセス修飾子は、finalと組み合わせて使われることもよくあります。finalはアクセス範囲ではなく「変更・拡張の可否」を制御する修飾子です。
例えばpublic finalクラスにすると、「誰からでもアクセスできるが、継承はできない」クラスになります。
protected finalメソッドであれば、「サブクラスからアクセスはできるが、オーバーライドはできない」メソッドになります。
アクセス範囲と変更可否を別々にコントロールしたい場合に活用しましょう。
よくある質問
Q1. Javaのアクセス修飾子は何種類ありますか?
A1. public・protected・default・privateの4種類です。この順にアクセス制限が緩いものから厳しいものへと段階的に設定されています。
Q2. アクセス修飾子を何も書かない場合はどうなりますか?
A2. defaultアクセスレベル(package-private)になります。同じパッケージに所属するクラスからのみアクセス可能です。ただし、インターフェースのメンバーは暗黙的にpublicになります。
Q3. protectedとdefaultの違いは何ですか?
A3. どちらも同一パッケージ内からアクセス可能ですが、protectedは別パッケージであってもそのクラスを継承したサブクラスからアクセスできます(サブクラス自身を通したアクセスに限ります)。defaultは別パッケージからは一切アクセスできません。
Q4. フィールドにはどのアクセス修飾子を使うべきですか?
A4. 原則としてprivateにします。カプセル化の原則に従い、外部から直接アクセスできないように隠蔽し、必要な場合はpublicなゲッター・セッターを用意します。
Q5. アクセス修飾子を選ぶときの判断基準は何ですか?
A5. 「可能な限りアクセス範囲を狭くする」という最小権限の原則に従います。まずprivateで定義できないか検討し、必要に応じてdefault、protected、publicへと段階的に範囲を広げます。
Q6. コンストラクタをprivateにするとどうなりますか?
A6. クラス外部から直接newできなくなります。インスタンスを1つに制限するシングルトンパターンなど、生成方法を制御したい設計で使われます。
まとめ|アクセス修飾子を理解して安全なコードを書く
最後に、重要なポイントをまとめます。
4つのアクセス修飾子の使い分けを再確認
- public: 誰でもアクセスOK。外部に公開するAPI。
- protected: パッケージ内 + 別パッケージのサブクラス。継承が前提。
- default: パッケージ内のみ。パッケージの部品。
- private: クラス内のみ。クラスの内部実装。原則これを使う。
迷ったときは、最も厳しいprivateから検討し、必要に応じて少しずつアクセス範囲を広げていくのが鉄則です。
アクセス修飾子を意識することが設計力の第一歩
アクセス修飾子を適切に使い分けることは、単なる文法ルールの話ではありません。
それは、クラスの責務を考え、いかにして安全で変更に強い部品を作るかという、ソフトウェア設計そのものに深く関わっています。
「この情報はどこまで見せるべきか?」と常に自問自答する習慣が、あなたのコードを一段上のレベルへと引き上げてくれるでしょう。
ぜひ、今日からのコーディングで意識してみてください。
| REV. | DATE | 内容 |
|---|---|---|
| 3 | 2026-10-04 | 記載内容の事実確認と修正 |
| 2 | 2026-09-04 | 2026年9月時点の情報で全体を見直し |
| 1 | 2025-10-26 | 初版 |


