2

I am new please dont mind if you find the question dumb.I was messing with singleton code.I changed it a bit(My question has nothing to do with singleton and yes I have removed single instance check).My question is though a class instance in java can only be one why there are two static class "instance" in output(see hash).I know "new" keyword will give a new memory address(thats what is getting printed in hash) but isn't static class instance supposed to be one?So I am getting two hashes for printing object instance,static variable k has same value,which is fine.

public class Singleton { private static Singleton instance; static int k; public static Singleton getInstance(){ try{ instance = new Singleton(); System.out.println(instance); }catch(Exception e){ throw new RuntimeException("Exception occured in creating singleton instance"); } return instance; } public static void main(String[] ar) { Singleton c1=Singleton.getInstance(); c1.k=1; Singleton c2=Singleton.getInstance(); c2.k=2; System.out.println(c1.k); System.out.println(c2.k); } } 

Output:

Singleton@15db9742 Singleton@6d06d69c 2 2 
9
  • what are you trying to ask here ? Commented Feb 24, 2017 at 8:31
  • 2
    Your code isn't a singleton, you produce a new instance each time getInstance() is called. Commented Feb 24, 2017 at 8:34
  • static means only 1 variable instance. It has nothing do with how many object instances you create. Commented Feb 24, 2017 at 8:34
  • 2
    There is no such thing as a 'static class instance' in Java; your question seems to be based on a lack of understanding the basics of Java. You just have a static field in your class that contains the last instance you created. You are getting two different instances, because that is what your code does: creating a new instance each time the getInstance() method is called. Commented Feb 24, 2017 at 8:39
  • 1
    Again, this is basic Java. It is just a field, and it can be (re)assigned at any time. The difference with a non-static field is that the field is owned by the class instead of by an instance of that class. And static Singleton s=new Singleton() is perfectly allowed, as long as that definition is in a class body, not in a method body. Commented Feb 24, 2017 at 8:56

5 Answers 5

4

Your variable instance is shared among your two objects but the object it's pointing to is changed when you call instance = new Singleton();

I guess what you're looking for is this.

public class Singleton { public static Singleton instance; //field is made public so we can print it from main class (just to debug) static int k; public static Singleton getInstance(){ try{ instance = new Singleton(); }catch(Exception e){ throw new RuntimeException("Exception occured in creating singleton instance"); } return instance; } public static void main(String[] ar) { Singleton c1=Singleton.getInstance(); c1.k=1; Singleton c2=Singleton.getInstance(); c2.k=2; //notice that both of the instance variables of c1 and c2 are printed //after we've initialized all of them. System.out.println(c1.instance); System.out.println(c2.instance); System.out.println(c1.k); System.out.println(c2.k); } } 

here you'll get same value for both instance variables

Output

Singleton@6d06d69c Singleton@6d06d69c 2 2 

The idea is to print the values after instance variable is initialized for all objects. The most recent initialization will override all previous initializations.

Sign up to request clarification or add additional context in comments.

6 Comments

Yes exactly!you cleared my doubt.But why is a static instance be allowed to be created by new?
@Vishal it depends upon the requirements. Let's suppose that in your class, you want to find how many times it was initialized. A static instance comes handy in this type of situation as we can create a field named private static int counter = 0 and we increment it in class's constructor. As this counter variable will be shared among all the objects, the same variable will count all the instances. If we don't make it static, each time a object is initialized, a new instance of counter is created and it will start from zero.
yes exactly!you cleared my doubt.But why is static being allowed to be initialised by new?I mean since objects shouldnt be used in static context and here I am initializing "instance" here with new Singleton(); Moreover Singleton.class can be used directly. static Singleton s=new Singleton() is not allowed which is correct.
No. We can't use Singleton.class to initialize, it indicates class reference and it doesn't initialize object. The point is static variable needs an object to hold-on to. That's why we initialize it using new. The difference is if a static variable is initialized using new, that same object will be shared across all instances, whereas if we don't make it static, then all the new objects will start with a null.
@Vishal yes that's a restriction imposed by java language specification. You cannot declare any field as static inside any method in java. Only class variables (fields) and methods can be static. See this answer as why : static variable in static member function in JAVA
|
2

Your singleton is not such..

everytime you call getInstance you generate a new instance instead of checking if the static object "instance" is null or not..

that is the reason why you get this:

Singleton@15db9742 Singleton@6d06d69c 

which clearly shows 2 instances of the class Singleton

Comments

1

As mentioned above, your problem here lies in the fact that you don't guard your instantiation.

Also to add a little bit more to @Ghislain Fourny's answer, to be sure you don't instantiate 2 classes in a multi-threading context add the keyword "synchronized" to the method getInstance.

 public static synchronized Singleton getInstance(){ try{ if(instance == null) { instance = new Singleton(); } System.out.println(instance); }catch(Exception e){ throw new RuntimeException("Exception occured in creating singleton instance"); } return instance; 

}

Comments

0

The thing is that in your getInstance method you always create a new instance object.

That is, while your actual instance is static, i.e. a class attribute, it is overwritten everytime you call getInstance.

To solve this, you should check if instance is null, and only then create a new object.

if(instance == null) instance = new Stingleton(); return instance; 

Comments

0

This is because a guard is missing to only create the singleton once.

public static Singleton getInstance(){ try{ if(instance == null) { instance = new Singleton(); } System.out.println(instance); } catch(Exception e){ throw new RuntimeException("Exception occured in creating singleton instance"); } return instance; } 

Without this guard, there is still only one static instance, but this instance is overwritten the second time.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.