tags:

views:

224

answers:

5

Just i was thinking about the other ways of writing singleton class. So is this class considered as a singleton class?

      public class MyClass{
            static Myclass myclass;

            static { myclass = new MyClass();}

            private MyClass(){}

            public static MyClass getInstance()
            { 
                return myclass;
            }
       }

as the static block run only once.

+5  A: 

No, it is not. You didn't declare myClass private static final, nor the getInstance() is static. The code also doesn't really compile.

Here's the Singleton idiom:

public class MyClass {
    private static final MyClass myClass = new MyClass();

    private MyClass() {}

    public static MyClass getInstance() {
        return myClass; 
    }
}

It should be private, so that nobody else can access it directly. It should be static so that there's only one of it. It should be final so that it cannot be reassigned. You also need to instantiate it directly during declaration so that you don't need to worry (that much) about threading.

If the loading is expensive and you thus rather prefer lazy loading of the Singleton, then consider the Singleton holder idiom which does initialization on demand instead of during classloading:

public class MyClass {
    private MyClass() {}

    private static class LazyHolder {
        private static final MyClass myClass = new MyClass();
    }

    public static MyClass getInstance() {
        return LazyHolder.myClass;
    }
}

You should however put big question marks whether you need a Singleton or not. Often it's not needed. Just a static variable, an enum, a factory class and/or dependency injection is often the better choice.

BalusC
sorry i will change it now.
GK
Also look at the *Initialization on demand holder idiom* http://en.wikipedia.org/wiki/Initialization_on_demand_holder_idiom
pjp
Thanks, updated the answer.
BalusC
Minor nitpick, you are still doing initialization during classloading, the changes is that it is now the classloading of the private nested class, not the public class.
james
+5  A: 

Here's one more way to do it :

public enum Singleton{
  INSTANCE("xyz", 123);

  // Attributes
  private String str;
  private int i;

  // Constructor
  Singleton(String str, int i){
    this.str = str;
    this.i = i;
  }
}

According to Josh Bloch's Effective Java, this is the best way to implement Singleton in Java.

missingfaktor
Agreed, this instance will be a singleton at the level of the classloader.
gpampara
A: 

Using your example and using the GoF's way of implementing it:

public class MyClass{
    private static Myclass instance;

    private MyClass(){
        //Private instantiation
    }

    public static synchronized MyClass getInstance()  //If you want your method thread safe...
    { 
        if (instance == null) {
            instance = new MyClass();
        }

        return instance;
    }
}

Hope this helps:

The Elite Gentleman
That should be "return instance"
phisch
Thanks...I updated it...thanks for seeing my mistake.
The Elite Gentleman
A: 

Here is how I do it. It is faster, because it only requires a synchronized block when the instance is created.

public class MyClass
{
private static MyClass INSTANCE=null;

private MyClass()
  {
  }

public static MyClass getInstance()
  {
  if(INSTANCE==null)
     {
     synchronized(MyClass.class)
       {
       if(INSATCNE==null) INSTANCE=new MyClass();
       }
     }
  return INSTANCE;
  }

}
Pierre
double checked locking is broken.
james
to fix the double-checked locking idiom in J2SE 5 and higher, set your variable as volatilee.g. private static volatile MyClass INSTANCE=null;
The Elite Gentleman
many thanks ! nice to know !
Pierre
A: 

Your class (original code, before editing):

    public class MyClass{
        Myclass myclass;

        static { myclass = new MyClass();}

        private MyClass(){}

        public MyClass getInstance()
        { 
            return myclass;
        }
   }

is not a real singleton:

  1. the field myclass is not private, can be read and changed from outside (assuming you got an instace to do it on
  2. the field myclass is not static, can not be accessed in the static constructor (compilation error)
  3. the getInstance() method is not static, so you need an instance to call it


The actual code:

    public class MyClass{
        static Myclass myclass;

        static { myclass = new MyClass();}

        private MyClass(){}

        public static MyClass getInstance()
        { 
            return myclass;
        }
   }

still has myclass not being private (nor final)... declaring it final would help to prevent it being unintentionally changed from inside the class.

    private static final Myclass myclass;
Carlos Heuberger