Java の本を読み始めたばかりで、疑問に思いました。何も指定されていない場合、デフォルトのアクセス指定子はどれですか?
12 に答える
デフォルトの可視性は「package-private」として知られています (ただし、これを明示的に使用することはできません)。これは、クラスが属する同じパッケージ内からフィールドにアクセスできることを意味します。
mdma が指摘したように、デフォルトが「パブリック」であるインターフェースメンバーには当てはまりません。
Java のアクセス指定子を参照してください
デフォルトの指定子はコンテキストによって異なります。
クラスおよびインターフェイス宣言の場合、デフォルトはパッケージ プライベートです。これは、保護されたものとプライベートなものの中間に位置し、同じパッケージ内のクラスのみにアクセスを許可します。(保護はこのようなものですが、パッケージ外のサブクラスへのアクセスも許可します。)
class MyClass // package private
{
int field; // package private field
void calc() { // package private method
}
}
インターフェイス メンバー (フィールドとメソッド) の場合、既定のアクセスは public です。ただし、インターフェイス宣言自体はデフォルトでパッケージ プライベートになることに注意してください。
interface MyInterface // package private
{
int field1; // static final public
void method1(); // public abstract
}
宣言がある場合
public interface MyInterface2 extends MyInterface
{
}
MyInterface2 を使用するクラスは、スーパー インターフェイスから field1 と method1 を見ることができます。これは、MyInterface 自体の宣言を見ることができなくても、パブリックであるためです。
アクセス指定子が指定されていない場合は、クラスおよびクラス メンバーに対するパッケージ レベルのアクセスになります (これには明示的な指定子はありません)。インターフェイス メソッドは暗黙的にパブリックです。
デフォルトの可視性 (キーワードなし) はpackageです。これは、同じパッケージにあるすべてのクラスで利用できることを意味します。
興味深いことに、protectedはサブクラスだけでなく、同じパッケージ内の他のクラスにも可視性を制限しません。
それは物によります。
最上位の型 (つまり、別の型内で宣言されていないクラス、列挙型、インターフェイス、および注釈型) は、既定でパッケージ プライベートです。( JLS §6.6.1 )
クラスでは、すべてのメンバー (フィールド、メソッド、およびネストされた型宣言を意味します) とコンストラクターは、既定でパッケージ プライベートです。( JLS §6.6.1 )
- クラスに明示的に宣言されたコンストラクターがない場合、コンパイラーは、クラスと同じアクセス指定子を持つデフォルトのゼロ引数コンストラクターを挿入します。( JLS §8.8.9 ) デフォルトのコンストラクターは、常に public であると誤解されることがよくありますが、まれに同等ではない場合があります。
列挙型では、コンストラクターはデフォルトでプライベートです。実際、enum コンストラクターは非公開でなければならず、それらを public または protected として指定するのはエラーです。列挙定数は常にpublicであり、アクセス指定子を許可しません。enum の他のメンバーは、デフォルトでパッケージ プライベートです。( 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 )。そのため、メソッドには内部的にアクセス指定子が必要です。javac によってコンパイルされたクラスと、16 進エディターを使用して Eclipse のコンパイラーによってコンパイルされたクラスを調べたところ、どちらもメソッドがpackage-privateとして生成されることがわかりました。ただし、メソッド名では文字と文字が無効である<clinit>()
ため、言語内で呼び出すことはできません。また、リフレクション メソッドはその存在を否定するように組み込まれているため、実質的にそのアクセス指定子はno accessです。このメソッドは、クラスの初期化中に VM によってのみ呼び出すことができます。<
>
インスタンス初期化ブロックは、個別のメソッドとしてコンパイルされません。それらのコードは各コンストラクターにコピーされるため、リフレクションであっても個別にアクセスすることはできません。
デフォルトのアクセス指定子はpackageです。クラスは同じパッケージ内の他のクラスのメンバーにアクセスできますが、パッケージの外部ではプライベートとして表示されます。
詳しくはこちらをご覧ください。デフォルトはprivate/public/protectedのいずれでもなく、完全に異なるアクセス仕様です。広く使用されているわけではありません。私は、アクセス定義をより具体的にすることを好みます。
キーワードのJava 8使用法を更新しますdefault
。他の多くの人が指摘しているように、デフォルトの可視性 (キーワードなし)
フィールドは、クラスが属する同じパッケージ内からアクセスできます。
Java 8の新しい機能 ( Default Methods )と混同しないようにしてください。これにより、default
キーワードでラベル付けされたインターフェイスが実装を提供できるようになります。
参照:アクセス修飾子