I've gone back and read the Java Language Specification and maybe I am missing it but it seems to not address the following situation:
publicclass X
{
privatestatic X myOwnX = new X();
publicstatic getX()
{
return myOwnX;
}
private X()
{
// do stuff
}
}
I'm not exactly sure what is supposed to occur here but I can tell you what we are observing - inconsistent and hard to reproduce bugs in the singleton.
This was done by a new programmer and when I had her change the code as follows, the problems seem to have vanished:
publicclass X
{
privatestatic X myOwnX;
publicstatic getX()
{
if (myOwnX == null)
myOwnX = new X();
return myOwnX;
}
private X()
{
// do stuff
}
}
This at least makes sense to me in that the class variable is not being initialized by a static initializer that is supposed to run when the class is being intialized, and yet trying to load an instance of itself.
I am not even sure the first code example should be legal Java but the compiler did not complain and we saw weirdness at runtime. She was writing a singleton to manage database connection objects for a Java application. As soon as she changed the construct the inconsistent errors stopped.
Again, if anyone can give me a pointer to the right section of the Java Language Specification, or to any other authoritative source so that I can understand what happened here better, I'd appreciate it.
That is an interesting problem. Not sure what exactly is going on, but I would be interested to see if using the keyword "final" makes any difference in the first example:
privatestaticfinal X myOwnX = new X();
Also your getX() method is missing its return type. It should be written as:
I don't see any problem with the first code snippet, you should be able to create a singleton this way.
The only difference between the two implementations is that the first will result in initialization of the singleton at class-load time while the second doesn't initialise until first call of getX().
I'd be interested to see what the outcome of this is. Are you sure the constructor wasn't being called somehow?