0

I wrote a program to call a singleton class from inside the class main. I also wrote an other class from which I am trying to create a object for the Singleton class. I found that I am able to create only one object when I tried from the other class but when I tried to call the method from the same class it creates more than one object. I couldnt understand what is different from same class main method and other class main method. Here are the classes:

SingleTonClass.java

public class SingleTonClass {

    private static SingleTonClass obj = null;

    private SingleTonClass() {
        System.out.println("Private Constructor is called");
    }

    public static SingleTonClass CreateObj() {
        if (obj == null) {
            obj = new SingleTonClass();
        }
        return obj;
    }

    public void display() {
        System.out.println("The Ojecte creation complete");
    }

    public void display1() {
        System.out.println("The second obj creation is comeplete");
    }

    public static void main(String[] args) {
        SingleTonClass stc = new SingleTonClass();
        SingleTonClass stc1 = new SingleTonClass();
        SingleTonClass stc2 = new SingleTonClass();
        // stc.display();
        // stc1.display1();

    }
}

SingleTonClassTest.java

public class SingleTonClassTest {

    public static void main(String[] args) {
        SingleTonClass stc=SingleTonClass.CreateObj();
        SingleTonClass stc1=SingleTonClass.CreateObj();
        SingleTonClass stc2=SingleTonClass.CreateObj();
    }
}
hpopiolkiewicz
  • 3,281
  • 4
  • 24
  • 36
user2980176
  • 21
  • 1
  • 1
  • 5

5 Answers5

3

Rather than doing:

private static SingleTonClass obj=null;

You should use: (sorry for changing your weird class name at the same time).

private static final Singleton INSTANCE = new Singleton();

To instantiate the only instance of your Singleton.

After that, you are not going to do some mystical retrieval like:

public static SingleTonClass CreateObj()
    {
        if (obj==null)
        {
            obj= new SingleTonClass();
        }
        return obj;
    }

Instead, you should define getInstance() method for retrieving your Singleton.

public static Singleton getInstance() {
    return INSTANCE;
}

After these modiciations, your Singleton class should look like the following:

public class Singleton {

    private static final Singleton INSTANCE = new Singleton();

    private Singleton() {
        // This is called only once
        System.out.println("Private Constructor is called");
    }

    public static Singleton getInstance() {
        return INSTANCE;
    }

    public static void main(String[] args) {

        // Even if you ask 100 times, this will only return the same INSTANCE
        Singleton stc  = Singleton.getInstance();
        Singleton stc1 = Singleton.getInstance();
        Singleton stc2 = Singleton.getInstance();

    }

}

And running it will, output:

Private Constructor is called

to your cmd or terminal.

As a final note, as @Swapnil stated already: private Singleton() { ... } declaration is used to indicate that only the Singleton class itself is able to create the instance, which makes sense and rather than doing private static final Singleton INSTANCE = new Singleton(); you can further optimize your code by using an enum constant to store instance (noted by @JonK). For further reading I recommend: singleton pattern in java

Cheers.

Community
  • 1
  • 1
Mauno Vähä
  • 9,688
  • 3
  • 33
  • 54
  • The recommended approach these days is to have the instance as an enum constant as opposed to a `private static final` field – JonK Jul 23 '14 at 16:30
2

The whole point of having a private constructor in implementing a singleton pattern is that you shouldn't be able to invoke it from outside the class, to avoid object creation directly. You're invoking it from inside the class. Hence, the problem.

Singleton is no magic, you need to have a method like getInstance() inside your singleton and this method should ensure there's only once instance.

Swapnil
  • 8,201
  • 4
  • 38
  • 57
1

Rather than creating new object of Singleton class every time get the instance of singleton class. There are various ways to define singleton class. Here is one way to crate thread safe Singleton class. for more check out this link http://www.journaldev.com/1377/java-singleton-design-pattern-best-practices-examples#bill-pugh-singleton

public class BillPughSingleton {

private BillPughSingleton(){}

private static class SingletonHelper{
    private static final BillPughSingleton INSTANCE = new BillPughSingleton();
}

public static BillPughSingleton getInstance(){
    return SingletonHelper.INSTANCE;
}

}

Sadashiv
  • 841
  • 11
  • 19
0

Singleton Class: We can create only one object of this class.

Let's take an example:Since every thing in Java is object so I am giving you a real life example. You have a house and there is lock in it. This lock has only one key and if any one from outside wants to enter or access any thing in your house then he should have that unique key. Means this constraint applies only on outsiders. If anyone already present in the house then he can do anything and there is no restriction for him.

In the same way private constructor does not let any anyone to create second object of that class but you can make multiple objects within the same class because private methods only accessed by same class.

Singleton is Design pattern and here in your code design is like this, CreateObj() is static method of SingletonClass which checks if object is null then create the object by calling the constructor otherwise it is returning the same object.

Deepu--Java
  • 3,742
  • 3
  • 19
  • 30
  • I understand your explanation. Thankyou. My question is SingleTonClass stc= new SingleTonClass(); If I do this from outside the class, it wont allow me to create atleast a single object beacuse the constructor is not visible to me but if I do this SingleTonClass stc=SingleTonClass.CreateObj(); it is allowing me to create one object atleast. I dont understand why it is acting differently here. – user2980176 Jul 23 '14 at 16:16
  • Just making a constructor private doesn't ensure that it only ever gets invoked once. Furthermore, if you take reflection into consideration it doesn't even prevent it from being called externally. – JonK Jul 23 '14 at 16:17
  • SingleTonClass is the class which you want to make singleton that's why you make it's constructor private. But private works only for other classes not for same class. – Deepu--Java Jul 23 '14 at 16:18
  • @JonK please don't take reflection here because in that case private has no meaning. I am just giving the simple explanation for his confusion. – Deepu--Java Jul 23 '14 at 16:19
  • @DeepakTiwari Fair enough - but my other point was that just making the constructor private **isn't enough** to make a class a singleton. It's just one part of a larger design pattern. – JonK Jul 23 '14 at 16:21
  • @JonK If you read the question then you will get that he is more confused about private method than singleton patterns son my explanation is mostly 'private' oriented rather than singleton pattern. – Deepu--Java Jul 23 '14 at 16:25
  • @DeepakTiwari It's probably this line: "In the same way private constructor does not let any anyone to create second object of that class" - that isn't true. Private constructors can be invoked as many times as you like, but only from within the class. – JonK Jul 23 '14 at 16:25
  • @JonK please read other part of that line also "but you can make multiple objects from same class " – Deepu--Java Jul 23 '14 at 16:27
  • Which seems contradictory and confusing. Please note though that I'm not the downvoter - that's just my observation on why this might have been downvoted. – JonK Jul 23 '14 at 16:31
  • My question is,If If do this SingleTonClass stc=SingleTonClass.CreateObj(); from outside the class, it is still allowing me to create one object, ideally if it is calling the private constructor in this case, why is it working even once? – user2980176 Jul 23 '14 at 17:04
  • @user2980176 In that case it is calling private constructor but this constructor is called by the class itself(not by any other class) and according to private property we can call it from the same class. – Deepu--Java Jul 23 '14 at 19:01
-1

You can not make objects of singleton class outside the class because the constructor is private. Constructor instantiate the object. if the constructor itself is private then the object will never be instantiated outside the class rather you can use getInstance method. then you can access its features outside the class.

Deepanshu J bedi
  • 1,530
  • 1
  • 11
  • 23
  • If the constructor is public, will the class remain a singleton? – Swapnil Jul 23 '14 at 16:17
  • @Swapnil No, it won't, because anyone can then bypass the rest of the singleton pattern and instantiate the class directly at will. Having a private constructor is necessary if you want to follow any of the singleton patterns, but isn't enough by itself to make the class a singleton. – JonK Jul 23 '14 at 16:20
  • @JonK Lol. I wasn't asking a question. I was trying to point out *exactly* the same thing to Deepanshu. Because this question is about singleton. – Swapnil Jul 23 '14 at 16:21
  • @Swapnil Ah! I completely misinterpreted your comment then. – JonK Jul 23 '14 at 16:22
  • He was being sarsarcastic. I should delete this answer then :( .. thank you for a concept guys – Deepanshu J bedi Jul 23 '14 at 16:23