Christophe De Troyer
Christophe De Troyer

Reputation: 2922

Singleton instantiated with this

I have an assignment for school where I have to spot patterns in a certain given project. All is well (well, relatively..) but it seems that most patterns I find are some sort of variation. The singleton I had to find is no different.

The code is given below. The strange thing about this is that this class does not seem to instantiate with the following constructor, as one would expect:

public Singleton() {
    if (singleton == null) {
        singleton = new Singleton();
    }
}

However, it is instatiated with this (as you can see in the original code below)? In my understanding this creates some sort of static singleton? I debugged and saw indeed that the first time the constructor is called by

Singleton x = new Singleton();
        x.Print();

, it is indeed null. And this is a Singleton instance. However, shouldn't there be

private static Singleton singleton = new Singleton();

on top of the class instead of singelton = this;?

public class Singleton {

    private static Singleton singleton;

    public static Singleton getDefault() {
        return singleton;
    }

    /**
     * The constructor.
     */
    public Singleton() {
        if (singleton == null) {
            singleton = this;
        }
    }

    public void Print()
    {
        System.out.println("I'm a singleton!");
    }

}

I'm pretty sure it is indeed a singleton, it's just of the type I have never seen and I don't get reasoning behind it, that's what I'm basicly asking.

Upvotes: 2

Views: 599

Answers (4)

Alan
Alan

Reputation: 822

There is generally two approaches to creating a Singleton class, both are based on keeping the constructor private.
The first approach:

public class Singleton
{
  public static final Singleton INSTANCE = new Singleton();

  private Singleton{...}
}

You create an instance like this: Singleton single = Singleton.INSTANCE;

The second approach:

public class Singleton
{
  private static final Singleton INSTANCE = new Singleton();

  private Singleton(){...}

  public static Singleton getInstance(){ return INSTANCE; }

}

In this case, you create an instance like this: Singleton single = Singleton.getInstance(); The getInstance() method is then regarded as a public factory method.

As you can see, in both cases the new keyword is definitely used to create a single instance of the class, but because of the pattern used, there can only be one instance and no more. You don't need to use the "this" keyword. Hope this helps.

Upvotes: 1

Keerthivasan
Keerthivasan

Reputation: 12880

Your code has not followed the Singleton pattern. I have shown below a class following the Singleton pattern. this refers to the current object instance. When you initialize the singleton reference with this inside constructor, it calls the default (no-args) constructor and assigns it back to the this reference and then it is assigned to singleton class member variable

public class Singleton {

    private static Singleton singleton;

    public static Singleton getDefault() {
        if (singleton == null)
            singleton = new Singleton();
        return singleton;
    }

    /**
     * The constructor.
     */
    private Singleton() {
        System.out.println(singleton);
        if (singleton == null) {
                /*this will call a default constructor
                 *and instantiate Singleton object
                 */
            singleton = this;
        }
    }

    public void Print() {
        System.out.println("I'm a singleton!");
    }


    public static void main(String[] args) {
        Singleton singleton = Singleton.getDefault();
        System.out.println(singleton.Print());
    }
}

Hope you can understand!

Upvotes: 0

Suzon
Suzon

Reputation: 759

If we use singletone we do not need to create instance for use. Because when we are creating singletone then we are creating new instance if not created. Take a look of below code :

public class Singleton {
    private static Singleton singleton;

    private Singleton() {
    }

    public static Singleton getSingleton() {
        if (singleton == null) {
            singleton = new Singleton();
        }
        return singleton;
    }

    public void testSingleTone(){
        System.out.println("test");
    }

    public static void main(String[] args){
        Singleton.getSingleton().testSingleTone();
    }
}

Upvotes: 0

fonkap
fonkap

Reputation: 2509

I think you are confusing the meaning or this. this is not instantiating the class, this references the newly created instance. Then whenever someone calls your constructor a new instance is created (and returned) no matter you store in private static Singleton singleton; or not.

As well said @dic19 you must make your constructor private for preventing more than one instance to exist.

If the point is not to modify the code as you said, then the point is to report that this class is NOT a singleton.

You can check debugging:

    Singleton x = new Singleton();
    Singleton x1 = new Singleton();
    Singleton x2 = new Singleton();

You will see all three are different instances, being Singleton.getDefault() simply the first you created.

Upvotes: 0

Related Questions