我很惊讶地发现嵌套类的私有构造函数仍然可以从嵌套类中调用。例如:
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(){
}
}
}
这是否意味着无法在嵌套类上强制执行单例模式?或者我错过了一些基本的东西?
答案 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!!
...
}
}
注意问题......在这两种情况下......是抽象是打破自己的不变量。