2

I was surprised to see that a private constructor of a nested class is still callable from the nesting class. For example:

 public class A{
      public void foo(){
           //private constructor of B
           //can be called from A
           B b = new B();
      }

      //nested class
      public static class B{
          private B(){
          }
      }
 }

Does this mean that there is no way to enforce the singleton pattern on a nested class? Or am I missing something fundamental here?

4

3 に答える 3

3

コンストラクターだけでなく、プライベートフィールドやメソッドにもアクセスできます。

public class Main {

    public static void main(final String[] args) {
        final B b = new B();
        b.whut();
    }

    public static class B {
        private B() {
            System.out.println("hey");
        }

        private void whut() {
            System.out.println("wut?");
        }
    }

}

外部クラスは、ネストされたクラスのプライベートフィールドにアクセスできます。

http://docs.oracle.com/javase/tutorial/java/javaOO/nested.html

于 2013-01-17T22:19:15.743 に答える
1

これは、ネストされたクラスにシングルトンパターンを適用する方法がないことを意味しますか?

とにかく、Javaでシングルトン(アンチ)パターンを実装することは困難です。enums良い方法を提供し、それらはネスティングでも機能します:

これは、ネストされたクラスにシングルトンパターンを適用する方法がないことを意味しますか?

enum Outer {
    O;
    enum Inner { I }
}
于 2013-01-17T22:22:26.200 に答える
1

これは、ネストされたクラスにシングルトンパターンを適用する方法がないことを意味しますか?

それはあなたが「強制する」とはどういう意味かによります。

fooつまり、コンパイラに「シングルトン」不変条件を壊さないようにすることができますか?それなら「いいえ」です。(または、少なくとも、最初に「B」をネストされていないクラスにしない限り...)

ただし、外部クラスとネストされたクラスはすべて同じソースファイルで定義されているため、同じ抽象化単位の一部と見なす必要があります。(そして実際、A.foo()呼び出すことができるという事実A.B.Bは、後者が非常に現実的な意味で真実であることを意味します。)したがって、A抽象化の不変条件全体を維持することは責任を負い、その中のすべてが...の単一性を含みBます。

その観点から、foo不変条件を破るメソッドは、不変条件を破るネストされていない「シングルトン」クラスの仮想メソッドと同じです。例えば

public Single {
    private static Single s = new Single();
    public static Single getInstance() { return s; }
    private Single() { ... }

    public void foo() {
        Single ss = new Single();  // breaks the invariant!!
        ...
    }
}

問題に注意してください...どちらの場合も...抽象化がそれ自体の不変条件を壊しているということです。

于 2013-01-17T22:26:14.237 に答える