This question, like my previous question, references Effective Java. This time I have quite a few sub-questions.
-
A privileged client can invoke the private constructor reflectively with the aid of the
AccessibleObject.setAccessible()method. If you need to defend against this, modify the constructor.
How, exactly, can a private constructor be invoked? And what isAccessibleObject.setAccessible()? -
What approach do you experts follow with singletons?
// Approach A public class Test{ public static final Test TestInstance = new Test(); private Test(){ ... } . . . } // Approach B public class Test{ private static final Test TestInstance = new Test(); private Test(){ ... } public static Test getInstance() { return TestInstance; } . . . }Isn’t the second approach more flexible, in case we have to make a check for new instances every time or the same instance every time?
-
What if I try to clone the class/object?
-
a single-element enum type is the best way to implement a singleton.
Why? How?
Obviously a private constructor can be invoked by the class itself (e.g. from a static factory method). Reflectively, what Bloch is talking about is this:
Typically, the first is favoured. The second (assuming you were to test ifTestInstanceis null before returning a new instance) gains lazy-loading at the cost of needing to be synchronized or being thread-unsafe.I wrote the above when your second example didn’t assign the instance to
TestInstanceat declaration. As stated now, the above consideration is irrelevant.It’s not about flexibility, it’s about when the cost of creating the one (and only) instance is incurred. If you do option a) it’s incurred at class loading time. That’s typically fine since the class is only loaded once it’s needed anyway.I wrote the above when your second example didn’t assign the instance to
TestInstanceat declaration. As stated now, in both cases the Singleton will be created at class load.A singleton should not allow cloning for obvious reasons. A CloneNotSupportedException should be thrown, and will be automatically unless you for some reason implement
Cloneable.Examples for this are in the book, as are justifications. What part didn’t you understand?