Singleton + static variables confusion

Hi

I had a question regarding static variables in Singleton classes. Suppose I have a Singleton class like so,

publicclass Singleton{

publicstatic Singleton INSTANCE =new Singleton();

privateint x = 0;

privatestatic String s =null;

private Singleton(){

x = 5;

s ="fjgds";

}

publicint getX(){

return x;

}

public String getS(){

return s;

}

}

Now, this piece of code -

publicstaticvoid main(String[] args){

System.out.println(Singleton.INSTANCE.getX());

System.out.println(Singleton.INSTANCE.getS());

}

gives this output :

5

null

Why is 's' null?

Thanks,

Rajiv

[1664 byte] By [fieryDevelopera] at [2007-10-3 9:12:55]
# 1

Because static fields are initialised in the order they appear. When INSTANCE is initialized the s field is set to "fjgds", but then the s field's own initialiser sets it back to null.

One reason why it's not a good idea for constructors to have side effects. It's good practise, if you are going to code a singleton this way, to put it's initialiser at the end of the code.

malcolmmca at 2007-7-15 4:25:14 > top of Java-index,Java Essentials,Java Programming...
# 2
Thanks. That clears things. I settled for not setting the static modifier for the variables (except INSTANCE). Considering that there's going to be only one instance of this class, I guess this should not be a problem.
fieryDevelopera at 2007-7-15 4:25:14 > top of Java-index,Java Essentials,Java Programming...
# 3
Leaving the "= null" off the declaration of s would have done it too.So where's my dukes? ;)
malcolmmca at 2007-7-15 4:25:14 > top of Java-index,Java Essentials,Java Programming...
# 4

> Leaving the "= null" off the declaration of s would

> have done it too.

This is not a better solution as it may requires to set it null in some applications.

Better declare the string before the INSTANCE as follows:

public class Singleton {

private int x = 0;

private static String s = null;

public static Singleton INSTANCE = new Singleton();

private Singleton() {

x = 5;

s = "fjgds";

}

public int getX() {

return x;

}

public String getS() {

return s;

}

}

It will work perfectly.

If you declare the String after INSTANCE then the following flow will occure:

1. When you declare the INSTANCE public static Singleton INSTANCE = new Singleton();

Then it will initialize the string to fjgds.

2. private static String s = null;

will re-initialize the string to null

diptaa at 2007-7-15 4:25:14 > top of Java-index,Java Essentials,Java Programming...
# 5

>> Leaving the "= null" off the declaration of s would

>> have done it too.

>

>This is not a better solution as it may requires to set it

> null in some applications.

"String s;" sets s to null automatically. All fields are automatically set to null / 0.0 / 0 according to their type before the constructor runs.

I would suggest that as a matter of style a field should not be initialized both in the declaration and in a constructor:

private int x = 0;

private static String s = null;

private Singleton() {

x = 5;

s = "fjgds";

}

To me this raises the suspicion that the programmer is confused: he can't decide whether x should be 0 or 5. Extra code that doesn't do anything is something of a code smell.

sjasjaa at 2007-7-15 4:25:14 > top of Java-index,Java Essentials,Java Programming...
# 6
> To me this raises the suspicion that the programmer> is confused: he can't decide whether x should be 0 or> 5. Extra code that doesn't do anything is something> of a code smell.Please be specific to the original problem posted not to extra codes
diptaa at 2007-7-15 4:25:14 > top of Java-index,Java Essentials,Java Programming...
# 7

>"String s;" sets s to null automatically. All fields are automatically set to null /

>0.0 / 0 according to their type before the constructor runs.

But it rather suprised me to find that, in cases like this, explicity intialisation to null can make a difference (albeit, usually for the worse).

All fields are zero/null before the class intialisation phase actually begins, but if you explicitly set a field to null Java will include code to clear it in <clinit>. So, in this example, had the s field been declared without explicity initialisation then the resuts would have been different.

malcolmmca at 2007-7-15 4:25:14 > top of Java-index,Java Essentials,Java Programming...