
こんにちは、大学時代にプログラミングを始め、現在はエンジニアをしているuhablog(ウハブログ)です。
今回はJavaのアクセス修飾子について現役エンジニアであるuhablogが徹底的に解説していきます。
アクセス修飾子というのはJavaのメソッドやフィールドの前についているpublicやprivateのことです。
この記事では
- アクセス修飾子とは
- アクセス修飾子の種類
という基礎的な内容から、サンプルプログラムを用いた実践的な解説もしていきます。
Javaを勉強し始めた初学者の方やアクセス修飾子についていまいち理解できていない方におすすめの記事となっています!
ぜひ最後まで読んでいってください!
アクセス修飾子とは
Javaのプログラムを見たことある人・書いたことがある人であれば、メソッドやフィールドに対して「public」や「private」というものを見たことがある・知っている人は多いと思います。
この「public」や「private」というのがアクセス修飾子です。
このアクセス修飾子はメソッドやフィールドに対してアクセスの制限をかけています。
例えば、「このフィールドの値は外部で書き換えられたくない」というときにprivateを指定すると外部からの書き換えが不可能になります。
システムやプログラムが大規模になればなるほどどこからクラスが使われるかわかりません。
そうなったときに適切なアクセス修飾子を付与しておくことで、思わぬバグやエラーを防ぐことができます。
アクセス修飾子の種類
アクセス修飾子がメソッドやフィールドに対してアクセス制限をかけるものであることがわかりました。
ここからはそれぞれのアクセス修飾子について解説していきます。
Javaでのアクセス修飾子は次の4つがあります。
- public
- protected
- デフォルト(指定なし)
- private
それでは一つずつ見ていきましょう!
public
まずはpublicです。
publicが付けられたメソッドやフィールドはどこからでもアクセスすることが可能です。
一番制限が弱いアクセス修飾子となっています。
publicは「公共の」や「公開の」といった意味があるので、わかりやすいですね。
protected
protectedは同じパッケージのクラスからアクセスすることが可能です。
また違うパッケージであっても、継承しているサブクラスであれば利用可能になります。
デフォルト(アクセス修飾子の指定なし)
アクセス修飾子を指定しなかった場合はデフォルトとみなされます。
デフォルトは同じパッケージ内からのみ利用することが可能です。
private
privateは最も制限が強いアクセス修飾子です。
同じクラス内からのみアクセスが可能になります。
アクセス修飾子を一覧で見比べる
ここまでそれぞれのアクセス修飾子の違いを見てきました。
次の表は各アクセス修飾子の制限範囲をまとめた表です。
アクセス修飾子 | 同じクラス | 同じパッケージ | 継承したクラス(サブクラス) | 全て |
public | ○ | ○ | ○ | ○ |
protected | ○ | ○ | ○ | × |
デフォルト(指定なし) | ○ | ○ | × | × |
private | ○ | × | × | × |
下に行けば行くほど制限が強く、アクセス可能な範囲が狭くなっています。
アクセス修飾子をサンプルプログラムで解説!
ここまではアクセス修飾子について言葉で解説してきました。
ここからは実際にプログラムを見て、動きを確認していきましょう!
基準となるクラス
まずは基準となるクラスを準備します。
パッケージは「sampleA」、クラス名は「Base」としました。
このクラスはpublic, protected, デフォルト, privateの4つのアクセス修飾子がついたString型のフィールドを持っています。
各フィールドはstaticなフィールドにしています。
staticなフィールドにすることで、インスタンス化しなくても利用できるため、今回の検証では便利です。
これらのフィールドにアクセスできるかどうかで、アクセス修飾子の範囲を検証していきます。
mainメソッドを用意して、各フィールドを出力してみます。
package sampleA;
/**
* 基準となるクラス
* @author uhablog
*
*/
public class Base {
/**
* publicなフィールド
* どこからでもアクセス可能
*/
public static String publicStr = "publicなフィールドです";
/**
* protectedなフィールド
* 同じパッケージ、継承したクラスからアクセス可能
*/
protected static String protectedStr = "protectedなフィールドです";
/**
* デフォルト(アクセス修飾子なし)
* 同じパッケージ内からアクセス可能
*/
static String defoStr = "アクセス修飾子なしのフィールドです";
/**
* privateなフィールド
* このクラスからしかアクセスできない
*/
private static String privateStr = "privateなフィールドです";
/**
* 確認用メソッド
*/
public static void main(String[] args) {
System.out.println(publicStr);
System.out.println(protectedStr);
System.out.println(defoStr);
System.out.println(privateStr);
}
}
実行結果
全てのフィールドにアクセス可能なことが確認できました。
publicなフィールドです
protectedなフィールドです
アクセス修飾子なしのフィールドです
privateなフィールドです
同じパッケージ
次に同じパッケージ内に別のクラスを準備しました。
パッケージは「sampleA」、クラス名は「SamePackage」です。
このクラスからBaseクラスのフィールドにアクセスして出力します。
同じパッケージであるため、修飾子なしのフィールドにはアクセスできますが、privateなフィールドにはアクセスできません
package sampleA;
/**
* 基準となるクラスと同じパッケージ内のクラス
* @author uhablog
*
*/
public class SamePackage {
/**
* 動作確認用メソッド
* @param args
*/
public static void main(String args[]) {
// publicなフィールドを出力
System.out.println(Base.publicStr);
// protectedなフィールドを出力
System.out.println(Base.protectedStr);
// デフォルトのフィールドを出力
System.out.println(Base.defoStr);
// privateなフィールドは出力できない
// System.out.println(Base.privateStr);
}
}
実行結果
実行結果は次の通りです。
publicなフィールドです
protectedなフィールドです
アクセス修飾子なしのフィールドです
違うパッケージ、継承あり
次に違うパッケージでBaseクラスを継承した場合を確認してみます。
パッケージは「sampleB」クラス名は「ChildClass」としました。
違うパッケージですが、Baseクラスを継承しているのでprotectedなフィールドにはアクセスすることができます。
しかしアクセス修飾子がないフィールドと、privateなフィールドにはアクセスできません。
package sampleB;
import sampleA.Base;
/**
* 違うパッケージで、基準のクラスを継承する
* @author uhablog
*/
public class ChildClass extends Base {
/**
* 動作確認用メソッド
* @param args
*/
public static void main(String args[]) {
// publicなフィールドを出力
System.out.println(Base.publicStr);
// protectedなフィールドを出力
System.out.println(Base.protectedStr);
// デフォルトのフィールドは出力できない
// System.out.println(Base.defoStr);
// privateなフィールドは出力できない
// System.out.println(Base.privateStr);
}
}
実行結果
実行結果は次の通りです。
publicなフィールドです
protectedなフィールドです
違うパッケージ、継承なし
では最後に違うパッケージで、継承がなかった場合のパターンを検証します。
パッケージは「sampleB」クラス名は「SampleClass」としました。
このクラスではpublicなフィールドのみアクセスすることができます。
それ以外の3つのフィールドにはアクセスすることができません。
package sampleB;
import sampleA.Base;
/**
* 別パッケージで継承もしていないクラス
* @author uhablog
*/
public class SampleClass {
/**
* 動作確認用メソッド
* @param args
*/
public static void main(String args[]) {
// publicなフィールドを出力
System.out.println(Base.publicStr);
// protectedなフィールドは出力できない
// System.out.println(Base.protectedStr);
// デフォルトのフィールドは出力できない
// System.out.println(Base.defoStr);
// privateなフィールドは出力できない
// System.out.println(Base.privateStr);
}
}
実行結果
実行結果は次の通りです。
publicなフィールドです
protectedなフィールドです
アクセス修飾子の使い分け
4種類のアクセス修飾子があり、それぞれの違いがわかりました。
ではこのアクセス修飾子はどのように使い分ければ良いのでしょうか?
基本的に外部からアクセスされても良いものはpublic、外部からアクセスされたくないものはprivateをつけるようにしましょう。
ただ上記のような基準で考えたときに迷ってしまい、わからない場合は可能な限りアクセス制限を強くしましょう。
なので、迷ったらとりあえずprivateで宣言してしまって、後から外部からの参照が必要だなとなったときは都度アクセス制限を弱めていきましょう。
しかし闇雲にアクセス制限を弱くしていくと、思わぬバグにつながりますので、注意が必要です。
ゲッターやセッターなどを使うことも検討する必要があるでしょう。
まとめ
今回はJavaのアクセス修飾子について解説してきました。
アクセス修飾子はメソッドやフィールドに付与することができ、アクセス可能な範囲を制限しています。
アクセス修飾子にはpublic、protected、なし、privateの4つがあり、適切なアクセス修飾子をつけることが必要です。
挫折せずにプログラミングを学ぶためには?
僕はプログラミングで挫折した経験があります。
エラーの連続やエラーが解消しても思った通りに動かないといったことが原因で、プログラミングが嫌いでした。
「プログラミングって全然意味わからないし、全然楽しくない」そう思っていました。
原因は当時周りに聞ける人が誰もいなかったからです。
プログラミング学習をしていく上で周りに聞ける環境というのはとても大切です。

周りに聞ける人なんていない
そんな人におすすめなのが月額10,780円で現役エンジニアに質問できる、プログラミングスクールのFreeksです。
多くのプログラミングスクールが数十万円払って通うところを月額10,780円から通うことができるのはコスパが良いです。
しかもサブスク制で、自分のペースで学ぶことができ嫌になったらすぐにやめることができます。
「周りに誰も聞ける人がいなくて、エラーが解決できない」「プログラミング全然楽しくない」という方は、無料カウンセリングを受けてみて下さい。
【関連記事】Freeks評判、口コミ