是否有可能在java中有一个嵌套的单例?

时间:2013-01-17 22:11:28

标签: java singleton nested-class

我很惊讶地发现嵌套类的私有构造函数仍然可以从嵌套类中调用。例如:

 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(){
          }
      }
 }

这是否意味着无法在嵌套类上强制执行单例模式?或者我错过了一些基本的东西?

3 个答案:

答案 0 :(得分: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

答案 1 :(得分:1)

  

这是否意味着无法在嵌套类上强制执行单例模式?

无论如何,在Java中实现单例(反)模式是很困难的。 enums提供了一种很好的方式,它们也可以嵌套:

这是否意味着无法在嵌套类上强制执行单例模式?

enum Outer {
    O;
    enum Inner { I }
}

答案 2 :(得分:1)

  

这是否意味着无法在嵌套类上强制执行单例模式?

这取决于你所说的“强制执行”。

如果您的意思是,您是否可以让编译器阻止foo打破您的'单例'不变量 - 然后“否”。 (或者至少,除非你先把'B'作为非嵌套类......)

但是,外部类和嵌套类都在同一个源文件中定义,应该被视为同一抽象单元的一部分。 (事实上​​,A.foo()可以调用A.B.B这一事实意味着后者在非常真实的意义上是正确的。)因此,A及其中的所有内容都需要维护整个抽象的不变量......包括B的单身。

那个的角度来看,打破不变量的foo方法与打破不变量的非嵌套“单例”类的假设方法没什么不同; e.g。

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!!
        ...
    }
}

注意问题......在这两种情况下......是抽象是打破自己的不变量。