1

I have a singleton class with a static method getNext()

public class Sequence {

   private static Sequence  instance;
   private static int counter;

   private Sequence () { // note: private constructor
      counter = 0;
   }

   public static Sequence getInstance(){
      if(instance==null) { // Lazy instantiation
         instance = new Sequence(); 
      }
      return instance;
   }

   public static int getNext(){ return ++counter;}
}

In my test code I have a for loop which calls getNext() several times

public class TestSequence {
   public static void main(String[] args) {
      for (int i = 0; i < 5; i++)
         System.out.println(Sequence.getNext());        
   }

}

and output of it is

1
2
3
4
5

Why is that? With my understanding of static I thought that output always will be 1.

I understand use of static method that there is no need to create instance of the class (object). When object is not created, then every call to static getNext() method should increment new (virtual) instance variable counter = 0 and return it.

But my program behave exactly the same way as for non static method. Why? Probably I misunderstand something or simplify things.

blekione
  • 10,152
  • 3
  • 20
  • 26
  • 3
    Static doesn´t mean that it is initializing itself again every time you invoke `getNext`. You should rather read what static really means, because it seems that you don´t understand it. – SomeJavaGuy Oct 28 '15 at 06:41

4 Answers4

7

every call to static getNext() method should increment new (virtual) instance variable counter = 0 and return it

No, a static variable (as counter is) is a class variable, which means there's only one instance of it, so the same variable is incremented in each call to the static method.

You would get your expected behavior if counter wasn't static and you changed getNext() to create a new Sequence instance :

public static int getNext(){
    Sequence seq = new Sequence ();
    seq.counter += 1;
    return seq.counter;
}

But then Sequence wouldn't be a Singleton.

Eran
  • 387,369
  • 54
  • 702
  • 768
  • I see that, but why? Please read my understanding of `static` and please explain me where I'm wrong – blekione Oct 28 '15 at 06:42
  • 1
    @MarcinKruglik [here](http://stackoverflow.com/questions/413898/what-does-the-static-keyword-do-in-a-class) – SomeJavaGuy Oct 28 '15 at 06:43
  • @Kevin Esche thx for a link. My understanding was then wrong. Now I got it. Instead of creating new 'virtual' instance of class every time, only one 'virtual' instance is created. – blekione Oct 28 '15 at 06:48
0

This is because the counter field is also static (class scoped). So in your static method, which indeed doesn't require an instance, you increment a static variable which doesn't need a Sequence instance neither.

If you'd remove the static modifier from the counter field the code would not compile though, because you'd need an instance inside your getNext() method. You can fix this however by changing it to:

public static int getNext(){ return getInstance().counter++;}

Probably even better would be to do it:

public int getNext(){ return ++counter;}

and then use this code like this:

System.out.println(Sequence.getInstance().getNext());
makasprzak
  • 5,082
  • 3
  • 30
  • 49
  • I see how it's behaving, counter must be static otherwise it will throw compile time errors. But why it behaves this way – blekione Oct 28 '15 at 06:43
  • Because it's static, which means it's class scoped, as others explained. And it doesn't need to be static. I provided a proper solution. – makasprzak Oct 28 '15 at 06:45
  • The suggested code change wouldn't change the observed behaviour, and it is liable to throw `NullPointerExceptions` as well. – user207421 Oct 28 '15 at 06:48
  • @MarcinKruglik, consider what would be required to access a non-static field; an instance right? So, the errors are explaining why it behaves that way. You're trying to access a non-static field from a static context. Please think that through. – ChiefTwoPencils Oct 28 '15 at 06:49
  • And also @EJP - The suggested code was not meant to change the observed behaviour, but to explain how the proper singleton should look like. – makasprzak Oct 28 '15 at 06:57
  • @EJP I'm explaining what static modifier is, what will happen if you remove it and why. The code example helps me achieve this goal. Maybe you believe it's otherwise, hence no code examples in your answer. – makasprzak Oct 28 '15 at 11:02
0

You have a missunderstanding of what static means. It means not final or unchangable. Using static at method level does connect the method with your class and not with an instance of your class. The same applies to variables. Your counter variable is static as well, so every instance of Sequence does use the same variable and no instance specific one.

wumpz
  • 8,257
  • 3
  • 30
  • 25
  • It seem that I was understanding it opposite way than it is. Still have to learn a lot. But funny (or sad) that when I suggest my understanding to my tutor (I'm a student) he said that I'm right and changed `getNext()` and `counter` to non-static. – blekione Oct 28 '15 at 07:04
  • "Not final or unchangeable" isn't at issue, and isn't clear either. – user207421 Oct 28 '15 at 07:31
-1

new (virtual) instance variable counter = 0 and return it.

What 'new (virtual) instance variable counter?

It's static. That means it isn't an instance variable.

user207421
  • 305,947
  • 44
  • 307
  • 483
  • I use virtual as describing my understanding how static works. I may be wrong and I'm asking for clarification. I see how the code is working and I got it, but I don't understand why it behaves this way – blekione Oct 28 '15 at 06:45
  • 1
    @MarcinKruglik Because that is the behaviour of `static` variables. 'Virtual' has nothing to do with it whatsoever. If 'virtual' and/or 'instance' are part of your 'understanding' of `static`, you have a complete misunderstanding. – user207421 Oct 28 '15 at 06:46
  • At the end of my post I said that probably I misunderstand it and I was right. But thx to this great community I'm now understand it better and hope to use this knowledge wisely :). And when I will be member of stackoverflow for more than 5 years and have 161k of reputation then my terminology will be much more precise. – blekione Oct 28 '15 at 06:56
  • Only one way to get there, and that's to start now. It won't just happen by magic. – user207421 Oct 28 '15 at 08:15