2

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

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

这是否意味着没有办法在嵌套类上强制执行单例模式?还是我在这里遗漏了一些基本的东西?

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()can call的事实A.B.B意味着后者在非常真实的意义上是正确的。)因此,A维护整个抽象的不变量是 off 和其中的一切的责任……包括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 回答