web-dev-qa-db-ja.com

Javaのデフォルトコンストラクタのアクセス修飾子は何ですか?

特にコンストラクタを定義しない場合、コンパイラは非表示のゼロパラメータコンストラクタを挿入することは誰でも知っています。そのアクセス修飾子は公開されていると思いましたが、内部クラスの問題を処理する際に、多分私は間違っていました。これが私のコードです:

_public class Outer {
  protected class ProtectedInner {
    // adding a public constructor will solve the error in SubOuterInAnotherPackage class
    //public ProtectedInner() {}
  }
}
_

そして、別のパッケージにOuterのサブクラスがあります:

_public class SubOuterInAnotherPackage extends Outer {
  public static void main(String[] args) {
    SubOuterInAnotherPackage.ProtectedInner protectedInner 
      = new SubOuterInAnotherPackage().new ProtectedInner(); // Error!! Can't access the default constructor
  }
}
_

main()メソッドでエラーが発生しますが、ProtectedInnerクラスにパブリックコンストラクターを追加すると、そのエラーは解決されます。そのため、デフォルトのコンストラクタの修飾子はパブリックではないと考えています!では、デフォルトのコンストラクタのアクセス修飾子が何か教えてもらえますか?

30
jason

そのアクセス修飾子はパブリックだと思っていましたが、内部クラスの問題を処理すると、おそらく間違っていることがわかりました。

うん。確かに、私は数年前に同じ状況に陥っていました。エラーに驚きました(Guiceの注入により、見つけにくくなりました)。

重要なのは、仕様をチェックすることです。この場合は セクション8.8.9

クラス型では、クラスがpublicと宣言されている場合、デフォルトのコンストラクターに暗黙的にアクセス修飾子public(§6.6)が与えられます。クラスが保護されていると宣言されている場合、デフォルトのコンストラクターには暗黙的にアクセス修飾子が保護されています(§6.6)。クラスがプライベートとして宣言されている場合、デフォルトのコンストラクタには暗黙的にアクセス修飾子private(§6.6)が与えられます。それ以外の場合、デフォルトのコンストラクターには、アクセス修飾子がないことを意味するデフォルトのアクセス権があります。

したがって、この場合、コンストラクタは暗黙的にprotectedになります。

46
Jon Skeet

ジョンがかなりよく述べたことに加えて、これは視覚的な人のための画像の例です

クラスにコンストラクターがない場合、コンパイラーは自動的にデフォルトのコンストラクターを作成します。

上記のルールをうまく表現した例を次に示します。

enter image description here

詳細については、 ここ を参照してください。

1
thodorisbais

私が最近得たもう一つのことを指摘したいと思います。クラスのデフォルトコンストラクターを定義する場合、それはアクセス指定子が割り当てるものになります。例えば、

 public class A{
       A(){
       // do some stuff
       }
    }

ここで、デフォルトコンストラクターのアクセス指定子はパッケージアクセスであり、パブリックアクセス(クラスのアクセス)ではありません。しかしながら

 public class A{
       // no constructor is defined
    }

ここでコンパイラはあなたに共感し、アクセス指定子がクラスと同じになるデフォルトのコンストラクタを与えます、それはパブリックです。

1
Surendra Sharma