Javaのデフォルトのアクセス指定子は何ですか?


108

私はJavaの本を読み始めたところ、疑問に思いました。何も指定されていない場合、デフォルトのアクセス指定子はどれですか?


正しい用語は「アクセス修飾子」です。「指定子」という単語はJLSに表示されません。
ローン侯爵

回答:


116

デフォルトの可視性は「package-private」と呼ばれます(これを明示的に使用することはできません)。これは、クラスが属する同じパッケージ内からフィールドにアクセスできることを意味します。

mdmaが指摘したように、デフォルトは「public」であるインターフェースメンバーには当てはまりません。

Javaのアクセス指定子を参照してください


25
正しくない-インターフェースメンバーには該当しません。デフォルトのアクセスはパブリックです
mdma

2
実際には「パッケージプライベート」と呼ばれています。サードパーティのWebサイトは、規範的な参照ではありません。JLSのみを引用する必要があります。
ローン侯爵

81

デフォルトの指定子はコンテキストによって異なります。

クラスおよびインターフェース宣言の場合、デフォルトはパッケージプライベートです。これは保護とプライベートの中間にあり、同じパッケージ内のクラスのみにアクセスを許可します。(protectedはこのようなものですが、パッケージ外のサブクラスへのアクセスも許可します。)

class MyClass   // package private
{
   int field;    // package private field

   void calc() {  // package private method

   }
}

インターフェースメンバー(フィールドとメソッド)の場合、デフォルトのアクセスはパブリックです。ただし、インターフェイス宣言自体のデフォルトはプライベートパッケージであることに注意してください。

interface MyInterface  // package private
{
   int field1;         // static final public

   void method1();     // public abstract
}

宣言があれば

public interface MyInterface2 extends MyInterface
{

}

MyInterface2を使用するクラスは、MyInterface自体の宣言を見ることができない場合でもパブリックであるため、スーパーインターフェイスからfield1とmethod1を見ることができます。


1
「パッケージプライベート」(としてソースに記述されることもあります/* pp */)は、デフォルトアクセスの便利な名前にすぎません。JLS名ではありません。
トムホーティン-タックライン2010

10
@Tom-そうです、JLSは「デフォルトのアクセス」を使用します。「デフォルトはデフォルトのアクセスです」と書くこともできました。しかし、それはあまり役に立ちませんでした!
mdma 2010

16

アクセス指定子が指定されていない場合は、クラスおよびクラスメンバーに対するパッケージレベルのアクセス(これに対する明示的な指定子はありません)です。インターフェイスメソッドは暗黙的にパブリックです。


9

デフォルトの可視性(キーワードなし)はパッケージです。つまり、同じパッケージにあるすべてのクラスで使用できます。

興味深い注意点は、protectedは可視性をサブクラスだけでなく、同じパッケージ内の他のクラスにも制限しないことです。


8

それは物事によって異なります。

  • 最上位の型(つまり、クラス、列挙型、インターフェース、および別の型の内部で宣言されていない注釈型)は、デフォルトでパッケージプライベートです。(JLS§6.6.1

  • クラスでは、すべてのメンバー(フィールド、メソッド、ネストされた型宣言を意味します)とコンストラクターは、デフォルトでパッケージプライベートです。(JLS§6.6.1

    • クラスに明示的に宣言されたコンストラクターがない場合、コンパイラーは、クラスと同じアクセス指定子を持つデフォルトのゼロ引数コンストラクターを挿入します。(JLS§8.8.9)デフォルトのコンストラクターは通常、常にパブリックであると誤って説明されていますが、まれに同等ではありません。
  • 列挙型では、コンストラクタはデフォルトでプライベートです。実際、列挙型コントラクタープライベートである必要があり、それらをパブリックまたは保護対象として指定するとエラーになります。列挙型定数は常にpublicであり、アクセス指定子を許可しません。enumの他のメンバーは、デフォルトでpackage-privateです。(JLS§8.9

  • インターフェースと注釈型では、すべてのメンバー(つまり、フィールド、メソッド、およびネストされた型宣言)がデフォルトでパブリックです。実際、インターフェースと注釈型のメンバーはパブリックである必要があり、それらをプライベートまたは保護として指定するとエラーになります。(JLS§9.3から9.5

  • ローカルクラスは、メソッド、コンストラクター、または初期化子ブロック内で宣言された名前付きクラスです。それらは、それらが宣言されている{.. }ブロックをスコープとし、アクセス指定子を許可しません。(JLS§14.3)リフレクションを使用すると、他の場所からローカルクラスをインスタンス化でき、それらはpackage-privateですが、その詳細がJLSにあるかどうかはわかりません。

  • 匿名クラスはnew、クラス本体を式で直接指定して作成されるカスタムクラスです。(JLS§15.9.5)それらの構文はアクセス指定子を許可しません。リフレクションを使用すると、他の場所から匿名クラスをインスタンス化でき、それらとその生成されたコンストラクターは両方ともpackage-privateですが、詳細がJLSにあるかどうかはわかりません。

  • インスタンスおよび静的初期化子ブロックには言語レベル(JLS§8.6および8.7)でのアクセス指定子はありませんが、静的初期化子ブロックは<clinit>JVMS§2.9)という名前のメソッドとして実装されるため、メソッドは内部的にいくつかのアクセス指定子を持つ必要があります。16進エディターを使用してjavacおよびEclipseのコンパイラーによってコンパイルされたクラスを調べたところ、どちらもpackage-privateとしてメソッドを生成していることがわかりました。ただし、メソッド名で<clinit>()<>文字が無効であり、リフレクションメソッドはその存在を拒否するように組み込まれているため、言語内で呼び出すことはできません。そのため、アクセス指定子は事実上アクセスできません。このメソッドは、クラスの初期化中にVMによってのみ呼び出すことができます。インスタンス初期化子ブロックは個別のメソッドとしてコンパイルされません。コードは各コンストラクタにコピーされるため、リフレクションによっても個別にアクセスすることはできません。


7

defaultは、メソッドと変数のアクセス修飾子として使用されるキーワードです。
このアクセス修飾子を使用すると、クラス、変数、メソッド、またはコンストラクターが独自のクラスまたはパッケージからアクセスできるようになります。アクセス修飾子が存在しない場合にも設定されます。

  Access Levels
    Modifier    Class   Package Subclass  EveryWhere
    public        Y        Y       Y         Y
    protected     Y        Y       Y         N
    default       Y        Y       N         N
    private       Y        N       N         N

インターフェースでデフォルトを使用する場合、この例のようなメソッドをそこに実装することができます

public interface Computer {    
    default void Start() {
        throw new UnsupportedOperationException("Error");
    }    
}

ただし、8 Javaバージョンからのみ機能します

公式ドキュメント

Javaのアクセス修飾子


3

詳細はこちらをご覧ください。デフォルトは、private / public / protectedではなく、完全に異なるアクセス仕様です。これは広く使用されていないため、アクセス定義をより具体的にすることを好みます。


3

デフォルトのアクセス指定子はパッケージです。クラスは同じパッケージ内の他のクラスのメンバーにアクセスできますが、パッケージの外部ではプライベートとして表示されます


3

これは、Javaの作成者であるJames Goslingへのインタビューからのパッケージレベルの可視性に関する引用です。

Bill Venners:Javaには4つのアクセスレベルがあります。デフォルトはパッケージです。C ++の人々がすでに知っている3つのキーワードがプライベート、保護、パブリックだったので、パッケージアクセスをデフォルトにすることが便利かどうか、私はいつも疑問に思っていました。または、パッケージへのアクセスをデフォルトにする必要があると感じた特別な理由がある場合。

James Gosling:パッケージは一般的に、一緒に書かれたもののセットです。だから一般的に私は2つのことの1つをすることができました。1つは、常にドメインを与えるキーワードを入力することを強制することでした。または、デフォルト値があったかもしれません。そして問題は、何が賢明なデフォルトになるのか?そして、私は最も危険なことではないものに行きがちです。

したがって、パブリックをデフォルトにすることは本当に悪いことだったでしょう。人々が実際にはそれほど頻繁にプライベートメソッドを書かないからといって、プライベートをデフォルトにすることはおそらく悪いことでしょう。保護されたと同じこと。そして、私が持っているコードの束を見て、私はかなり安全な最も一般的なものはパッケージにあると判断しました。また、C ++にはパッケージの概念がなかったため、そのためのキーワードはありませんでした。

しかし、友人の概念よりも私はそれが好きでした。友人と一緒に、あなたは友人のすべてが誰かを列挙する必要があるからです。そのため、新しいクラスをパッケージに追加すると、通常、すべてのクラスに行く必要がありますそのパッケージ内のクラスとその友達を更新します。私はいつもお尻に完全な痛みを感じていました。

しかし、友達リスト自体は、ある種のバージョン管理の問題を引き起こします。そして、この友好的なクラスの概念がありました。そして、私がそれをデフォルトにしたことの素晴らしいこと-私は問題を解決するので、キーワードはどうあるべきですか?

しばらくの間、実際にはフレンドリーなキーワードがありました。しかし、他のすべては「P」で始まるので、「PH」で「意地悪」になりました。しかし、それはたぶん1日だけそこにありました。

http://www.artima.com/intv/gosling2P.html


2

キーワードのJava 8の使用法を更新しますdefault。他の多くの人が指摘したとおり、デフォルトの可視性(キーワードなし)

フィールドは、クラスが属する同じパッケージ内からアクセスできます。

キーワードでラベル付けされたときにインターフェースが実装を提供できるようにする新しいJava 8機能(デフォルトメソッド)と混同しないでくださいdefault

参照:アクセス修飾子



-2

まず最初に、Javaには「アクセス指定子」などの用語がないことを1つ言っておきます。すべてを「修飾子」と呼ぶ必要があります。最終的に、静的で、同期された、揮発性のものは修飾子と呼ばれます。パブリック、プライベート、保護された、デフォルトの抽象も修飾子と呼ばれるべきです。デフォルトは、物理的な存在はないがモディファイアが配置されていない場合のモディファイアであり、デフォルトのモディファイアとして扱われる必要があります。

これを正当化するために、1つの例を示します。

public class Simple{  
    public static void main(String args[]){  
     System.out.println("Hello Java");  
    }  
}  

出力は次のようになります。 Hello Java

ここで、publicをprivateに変更し、どのコンパイラエラーが発生するかを確認します。「ここでは修飾子privateは許可されていません」という結論が出ます。したがって、Javaには用語アクセス指定子がなく、すべてが修飾子であると言えます。


最初の文はスポットオンですが、外部クラスをプライベートにできないという事実は、Javaにアクセス指定子などがないことを証明していません。
ローン侯爵

@EJPこれは単なる例です。私が言っているのは、アクセス指定子という用語がc、ドットネットなどの他の言語で使用されていることですが、これを表すJavaの専門用語は修飾子です。Eclipseまたは他のIDEを使用する場合、新しいクラスの作成時に修飾子の名前を提供するように求められ、リストにパブリック、プライベート、アブストラクトなどを提供することが
わかります

私の例では、コンパイラがエラーメッセージを表示すると言いますが、プライベート修飾子は許可されていません。アクセス指定子プライベートのようなメッセージは許可されていません。したがって、私たちが言うべき専門用語は、Javaの修飾子であり、Javaのアクセス指定子ではありません
Sagar Raut
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.