0

I wrote the following code initially. The purpose was to ensure only one object of a class is created at any point of time.

public class singleinstance {
private static int instance;

public singleinstance(){
    if(instance != 0){
        throw new IllegalStateException("More than one instance");
    }
    System.out.println(instance);
    instance ++;
    System.out.println(instance);
}
}

later, when I checked internet to see if this is the best way to do this, I came across the term singleton, and using private constructors, and came across This link I tried the same code in its accepted answer section, but by defining a counter variable and printing it, and could see that the number of instance of class is more than one. I am pasting the code below.

public class Singleton {
private static int counter=0;
private static Singleton instance;

/**
 * A private Constructor prevents any other class from
 * instantiating.
 */
private Singleton() {
    // nothing to do this time
}

/**
 * The Static initializer constructs the instance at class
 * loading time; this is to simulate a more involved
 * construction process (it it were really simple, you'd just
 * use an initializer)
 */
static {
    instance = new Singleton();
}

/** Static 'instance' method */
public static Singleton getInstance() {
    return instance;
}

// other methods protected by singleton-ness would be here...
/** A simple demo method */
public int demoMethod() {
    counter++;
    return counter;
}
}

Singletontest.java

public class Singletontest {
public static void main(String[] args) {
    Singleton tmp = Singleton.getInstance();
    System.out.println(tmp.demoMethod());
    Singleton tmp1 = Singleton.getInstance();
    System.out.println(tmp1.demoMethod());
}
}

The test class, when executed, printed 1, 2, which means two instances of the class is created with the singleton class. If this is possible, why is it considered singleton? Please clear my understanding.

EDIT:: the call to the method incremented the value again. But again, I could alternately call the methods tmp1.demoMethod(), tmp.demoMethod() multiple times, which made me think that tmp and tmp1 are the two objects that are created. How do I confirm, or what are the things that I can look into, to confirm that this is just a single instance?

Community
  • 1
  • 1
scott
  • 1,557
  • 3
  • 15
  • 31
  • 5
    Its your demo method which increments this value, not constructor. Each call to this method will increment your counter. Better check if both instances are same or not. – SacJn Nov 19 '15 at 12:04
  • 1
    Just use an `enum`. Delete all this mess and pretend that it never happened... – Boris the Spider Nov 19 '15 at 12:07

7 Answers7

1

In your example, tmp and tmp1 is the same object instance. You can check it by printing both objects :

System.out.println(tmp);
System.out.println(tmp1);

After, you call the method on same object twice, and counter is incremented twice. But only one object of Singleton was created

Prim
  • 2,880
  • 2
  • 15
  • 29
1

Your conclusion is incorrect, getting increased number would imply precisely the opposite (that you have just one instance). But your counter is static, which means it is shared by all instances, so it is not usable as an argument

  1. make counter non-static. This means that each instance oof Singleton class will have its' own counter starting at 0
  2. then invoke your code. If you get 1, 2, you have just one instance of Singleton class. If you would get 1, 1, it would mean that you have two instances of Singleton class. But that won't happen

by the way, tmp and tmp1 are two references to the same instance

Jan Hruby
  • 1,477
  • 1
  • 13
  • 26
1

here tmp and tmp1 is the same object instance.if you try to print tmp and tmp1 it will be same. I mean it points to same Object.

Mukesh Kumar
  • 317
  • 1
  • 5
  • 16
0

It is not creating multuple instances. Your static variable just get incremented.

Considee statics as class variables, not instance variables.

  • But the static variable is incrementing because the object created is not destroyed right? – scott Nov 19 '15 at 12:09
  • 1
    @scott what makes you think that? Given that you increment it **for each method call**. Try calling it twice on the same _reference_ and see what happens... – Boris the Spider Nov 19 '15 at 12:10
  • For example. Comment out your instance creation static block and getInstance() method. Then make demo method a static one. Yhem comment out your calling method code for this instance and calla twice as follows `Singleton.demoMethod()`. Then you will see that your variable is getting incremented with no instances at all. – Bentharage Asela Nov 19 '15 at 12:23
  • @BoristheSpider Thank you, the call to the method incremented the value again. But again, I could alternately call the methods `tmp1.demoMethod, tmp.demoMethod()` multiple times, which made me think that tmp and tmp1 are the two objects that are created. How do I confirm, or what are the things that I can look into, to confirm that this is just a single instance? – scott Nov 19 '15 at 12:44
  • 1
    @scott use an `enum` and don't implement your own singleton pattern. Then you can rest assured that it's the same instance as it is guaranteed by the Java platform. – Boris the Spider Nov 19 '15 at 12:45
0

Here you are calling method from Singleton object only. First time when you call Singleton.getInstance(), you will get object with counter variable value set to 0.

After that you are calling demoMethod through singleton object and it will increment value of counter to 1. And again when you retrieve object through Singleton.getInstance(), it will give you same object instance with variable value 1 and that's why it's printing 2 when you call demoMethod through it.

Vimal Bera
  • 10,346
  • 4
  • 25
  • 47
0

Existing: You have declared counter variable as a static / class variable (shared across the multiple instances of same class).

private static int counter=0;

Inside the method demoMethod you're incrementing the counter with ++ operator so that each time when you invoke the method on instance, counter value will get increased - that's the reason it is printing as 1,2

You can try like this:

Declare counter variable as an instance variable inside the class

private int instance;

Now the output will come as 1,1

Ori Lentz
  • 3,668
  • 6
  • 22
  • 28
0

I prefer this way to create Singleton class.

public class Singleton {

private static Singleton instance;

private Singleton() {  
}

public static Singleton getInstance() {
    if(instance == null){
       instance = new Singleton();  
    }
    return instance;
}

}