web-dev-qa-db-ja.com

デフォルトのアクセス修飾子とは何ですか?

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

103
bennedich

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

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

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

113
KeatsPeeks

デフォルトの指定子はコンテキストに依存します。

クラスおよびインターフェイス宣言の場合、デフォルトはパッケージプライベートです。これは保護されたクラスとプライベートなクラスの間にあり、同じパッケージ内のクラスのみがアクセスできます。 (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を見ることができます。

79
mdma

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

15

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

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

9

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

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

  • クラスでは、デフォルトですべてのメンバー(フィールド、メソッド、ネストされた型宣言を意味する)とコンストラクターはpackage-privateです。 ( JLS§6.6.1

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

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

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

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

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

8
Boann

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のアクセス修飾子

4
Amadeu Antunes

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

3
abhi

詳細については、 here を参照してください。デフォルトはprivate/public/protectedではありませんが、完全に異なるアクセス仕様です。広く使用されているわけではないので、アクセス定義をより具体的にすることを好みます。

3
Brian Agnew

Javaの作成者であるジェームズゴスリングとのインタビューから、パッケージレベルの可視性についての引用を以下に示します。

Bill Venners:Javaには4つのアクセスレベルがあります。デフォルトはpackageです。 C++の人々が既に知っている3つのキーワードはprivate、protected、およびpublicであったため、パッケージアクセスをデフォルトに設定するのが便利かどうか、私はいつも疑問に思っていました。または、パッケージへのアクセスがデフォルトであると思われる特別な理由がある場合。

James Gosling:パッケージは、一般に、一種の一緒に書かれたもののセットです。したがって、一般的には、次の2つのいずれかを実行できます。 1つは、ドメインを与えるキーワードを常に強制することでした。または、デフォルト値を持っていた可能性があります。そして、問題は、賢明なデフォルトを作るものは何ですか?そして、私は最も危険性の低いものに行く傾向があります。

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

しかし、友人の概念よりも好きでした。友人の場合は、友人全員を列挙する必要があるため、パッケージに新しいクラスを追加すると、通常はすべてのそのパッケージのクラスを作成し、友達を更新します。これは、私がいつも痛烈な苦痛であることがわかりました。

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

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

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

3

更新Java 8defaultキーワードの使用法:他の多くの人が指摘しているようにデフォルトの可視性(キーワードなし)

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

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

参照: アクセス修飾子

2
Ahmad Sanie

Javaには「デフォルト」と呼ばれるアクセス修飾子があります。これにより、そのパッケージ内でのみそのエンティティのインスタンスを直接作成できます。

便利なリンクを次に示します。

Java Access Modifiers/Specifiers

1
kg11