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?
It depends what you mean by “enforce”.
If you mean, can you get the compiler to prevent
foofrom breaking your ‘singleton’ invariant – then “No”. (Or at least, not unless you make ‘B’ a non-nested class first …)However, the outer class and the nested classes are all defined in the same source file, and should be considered as part of the same unit of abstraction. (And in fact, the fact that
A.foo()can callA.B.Bmeans the latter is true in a very real sense.) Therefore, it is the responsibility offAand everything within it to maintain the entire abstraction’s invariants … including singleton-ness ofB.From that perspective, a
foomethod that breaks the invariant is no different to a hypothetical method on a non-nested “singleton” class that breaks the invariant; e.g.Note the problem … in both cases … is that the abstraction is breaking its own invariants.