Javaアクセス修飾子(Access modifiers)

アクセス修飾子は、publicprotectedprivateなどの修飾子の総称で、クラスやそのメンバーがどこからアクセス可能かを決定します。

アクセス修飾子

アクセス修飾子 概要
public すべてのクラスからアクセスできます。
protected 現在のクラスとサブクラスからアクセスできます。
なし(default) 現在のクラスと同じパッケージのクラスからアクセスできます。
private 現在のクラスからのみアクセスできます。

アクセス修飾子を省略した状態は、パッケージ内部でのみ自由にアクセスできるという意味で、パッケージプライベート(package private) と呼ばれます。

たとえば、次のコードでは各アクセスレベルの動作を確認できます。

package com.devkuma.basic.modifier;

public class ModAccess {
    public String pubVar = "public";
    protected String protVar = "protected";
    String packVar = "package private";
    private String priVar = "private";

    public void test() {
        // クラス内部では、すべてのレベルのメンバーにアクセスできます。
        System.out.println(this.pubVar);
        System.out.println(this.protVar);
        System.out.println(this.packVar);
        System.out.println(this.priVar);
    }

    public static void main(String[] args) {
        ModAccess m = new ModAccess();
        m.test();
    }
}

実行結果:

public
protected
package private
private

下のクラスは、上のModAccessのサブクラスです。

package com.devkuma.basic.modifier;

// ModAccessのサブクラス
public class ModAccessChild extends ModAccess {

    public void test() {
        System.out.println(this.pubVar);
        System.out.println(this.protVar);
        System.out.println(this.packVar);
        // System.out.println(this.priVar); // private変数にはアクセスできません。
    }

    public static void main(String[] args) {
        ModAccess mc = new ModAccessChild();
        mc.test();
    }
}

実行結果:

public
protected
package private

下のクラスは、上のModAccessとは継承関係がない別パッケージのクラスです。

package com.devkuma.basic.modifier.other;

import com.devkuma.basic.modifier.ModAccess;

// ModAccessと継承関係がない別パッケージのクラス
public class ModAccessOther {
    public static void main(String[] args) {
        ModAccess my = new ModAccess();
        System.out.println(my.pubVar);
        // protected以下のメンバーにはアクセスできません。
        // System.out.println(my.protVar);
        // System.out.println(my.packVar);
        // System.out.println(my.priVar);
    }
}

実行結果:

public

アクセス修飾子を指定する規則は、単に「要件を満たす範囲で、できるだけ狭くアクセス範囲を指定すること」です。

特に、package privateとpublic/protectedの間には大きな違いがあります。package private/privateはAPIが非公開であることを意味するため、コードを修正するときにも互換性の維持などを強く意識する必要はありません。しかし、public/protectedは公開APIなので、利用者への配慮が必要です。