This week's book giveaway is in the Jobs Discussion forum.
We're giving away four copies of Soft Skills and have John Sonmez on-line!
See this thread for details.
The moose likes Beginning Java and the fly likes Questions About Being Static Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Soft Skills this week in the Jobs Discussion forum!
JavaRanch » Java Forums » Java » Beginning Java
Bookmark "Questions About Being Static" Watch "Questions About Being Static" New topic
Author

Questions About Being Static

Jim Borland
Ranch Hand

Joined: Oct 26, 2009
Posts: 31
Following some code examples I found on the web via Google, I've created a singleton pattern which is used to restrict instantiation of a class to one object. It works great and solves a problem I've been having with my application, but I don't understand how it functions. I'm just a novice Java programmer and would appreciate someone answering these questions:



This class is accessed from another class using these lines of code:



Questions:

(1) the Singleton class starts out by declaring a variable "singleton" whose type is itself. That seems odd.

(2) the getInstance() method returns an object of itself (another oddity).

(3) the line -- if(singleton == null) -- will be true the first time because in its original declaration it was set equal to null. But, what about subsequent occasions? Where does the "singleton" object hang out between calls? How does the class retrieve it during a subsequent run?

(4) the first line in its call from another class -- Singleton singleton = Singleton.getInstance(); -- is also a mystery to me. The portion at the right (Singleton.getInstance() ) is a class name followed by the method call. Usually code at the right is "new" followed by the class name to create a new instance of that class. When is this class created the first time this call is made?

There's lots of static stuff here, and my Java textbook says the keyword static causes the member to belong to the class itself, not to an instance of the class. It's clear I don't understand the effect or ramification of something being static. Please educate me as to what's happening here (as I said, it works great!). Thank you.
John de Michele
Rancher

Joined: Mar 09, 2009
Posts: 600
Jim:

Answers to your questions:

1) That's not really that odd. It's not really any different from returning any other type.

2) No, it's not returning an object. It's returning a reference to the one existing object. You can have any number of references point to a single object.

3) Because the reference is static, and associated with a class not an object, the reference still points to the original object between calls.

4) What should happen in your getInstance() method is that is should check whether singleton is null (line 17). If it is null, it should create the single instance of Singleton and return a reference to it. Otherwise, it should just return a reference to it.

John.
Ernest Friedman-Hill
author and iconoclast
Marshal

Joined: Jul 08, 2003
Posts: 24187
    
  34

Hi,

1) You'll get used to it -- it's very common. Remember that a variable is a reference to an object -- a handle, a pointer, a name -- and not the object itself. Imagine I've got a business card in my pocket that says "Joe Smith, Attorney at Law." That's a reference to another Person, but you don't think it's odd that I carry it around, right?

2) Again, not really so odd, especially if you consider the Person analogy. You do know where babies come from, right?

3) You have actually stated exactly why this whole thing works. The first time through, the variable is null, and the object is created. All the other times through, it's not null, and the same old object -- stored in that variable you mentioned in #1, which is static, so it's stored with the class itself -- is returned.

4) "static" methods and member variables are attached to the class, not to an object. That means that you can call static methods without reference to an object: you can call then just using the name of the class. Also, static variables aren't part of an object, so the static method can refer to it without there being an object to contain it. So here you're asking the Singleton class itself, "give me your single instance," which then optionally creates, but definitely returns, an actual instance of the class.

There is actually a major problem with this class: the method getInstance() should be made "synchronized." If it's not, and multiple threads are calling getInstance() at about the same time, you can end up creating more than one object. oneTime() should really be synchronized too.


[Jess in Action][AskingGoodQuestions]
John de Michele
Rancher

Joined: Mar 09, 2009
Posts: 600
Another possibility to avoid threading issues is creating the singleton as a type-safe enum:

John.
Ernest Friedman-Hill
author and iconoclast
Marshal

Joined: Jul 08, 2003
Posts: 24187
    
  34

John de Michele wrote:Another possibility to avoid threading issues is creating the singleton as a type-safe enum:


Interesting! I haven't seen this before. I can't decide whether I like it or not. On the one hand, it does accomplish the goal; on the other hand, it's definitely (ab)using a feature for other than the intended purpose.
Jim Borland
Ranch Hand

Joined: Oct 26, 2009
Posts: 31
John & Ernest,

Thank you very much for your answers. Please verify that my thinking here is correct:

(1) Line # 7 is a reference or a pointer to a memory location that holds an object of type Singleton. The name of this reference (or pointer) is "singleton." This portion of memory set aside for Singleton starts out being "null" but later obtains an actual object (line # 28). Since it is "private" it can only be seen by this class.

(2) getInstance() returns "singleton" which is just a pointer to that location in memory.

(3) The second time through -- if(singleton == null) -- will be false since there is now an actual object stored in that memory location. The reference "singleton" still points to the original object in memory since it is "static" and associated with a class, not an object.

(4) So far, so good, but I'm still confused about this one. The first line in the other class -- Singleton.getInstance(); -- calls a method in a class that has not yet been instantiated (there is no object). I don't understand this. Prior to being constructed (no object) the class is just the Java code in the class file. Do we actually reach inside the Java code and run a method without first creating an object? Ernest's answer says: "you can call static methods without reference to an object: you can call them just using the name of the class." I don't get it.

As for the multiple thread issue, it's not a problem in my case because my application calls this class immediately when it first starts. However, I am going to add the edits you have suggested because I want to follow good programming practices.

Thanks again for your clear answers to my questions.
Ernest Friedman-Hill
author and iconoclast
Marshal

Joined: Jul 08, 2003
Posts: 24187
    
  34

Hi Jim,

I think you're really close, but a few things are a little fuzzy; let's see if I can help.

When the program starts there's a place set aside to hold a reference to a Singleton object. That reference is null, meaning that it has a special value which means "no object".

The space which eventually holds the object itself isn't set aside until this line executes:

singleton = new Singleton();

When this runs, the JVM allocates some memory, creates an object in it, and sets the value of "singleton" to refer to it. "singleton" isn't null anymore; now it refers to this new object.

Now, as far as "reaching into a class and running a method without creating an object": yep, exactly. You can do that with any static method. You can call a static method on any class without creating an instance of that class, and you can access static member variables without creating an object, either. The java.lang.System class has a few commonly-used static methods you may have used without thinking about it: System.currentTimeMillis(), System.arraycopy(). The java.lang.Math class has a whole bunch more: Math.sqrt(), Math.abs(), etc. You don't need a System or Math object to call any of these; you just call them.


Jim Borland
Ranch Hand

Joined: Oct 26, 2009
Posts: 31
So, would it be correct to say that line # 7 creates the intention to store an object of type Singleton in memory at some future time? If so, then where is the information stored when you set this to "null?"

Thank you for clarifying the way abstract methods function. It's starting to make some sense.

Thanks again!

P.S. Never mind. I reread your explanation

> When the program starts there's a place set aside to hold a reference to a Singleton object.
> That reference is null, meaning that it has a special value which means "no object".

Now I understand!
John de Michele
Rancher

Joined: Mar 09, 2009
Posts: 600
Ernest:

Actually, I got that example from Effective Java, 2E. Joshua Bloch recommends it to easily enforce singleton-ness.

John.
David Newton
Author
Rancher

Joined: Sep 29, 2008
Posts: 12617

Yeah, I think the enum-as-singleton pattern is catching on. I'm not sure it's going against enum's intentions, really, though--I thought they were singletons to make comparisons more idiomatic.
Muhammad Khojaye
Ranch Hand

Joined: Apr 12, 2009
Posts: 449

I am not sure whether we have any advantage of Enum Singleton pattern over inner class static holder idiom pattern.


http://muhammadkhojaye.blogspot.com/
David Newton
Author
Rancher

Joined: Sep 29, 2008
Posts: 12617

You don't have to write it.
Paul Clapham
Bartender

Joined: Oct 14, 2005
Posts: 18985
    
    8

Muhammad Ali Khojaye wrote:I am not sure whether we have any advantage of Enum Singleton pattern over inner class static holder idiom pattern.


If you make your singleton serializable, then you can create as many as you want by deserializing one which has been serialized. But when you deserialize an Enum object, you just get the original Enum, not a copy of it.
Ernest Friedman-Hill
author and iconoclast
Marshal

Joined: Jul 08, 2003
Posts: 24187
    
  34

Paul Clapham wrote:
If you make your singleton serializable, then you can create as many as you want by deserializing one which has been serialized. But when you deserialize an Enum object, you just get the original Enum, not a copy of it.


This is true and a good point -- but of course you can implement that yourself with readResolve() as well. It just makes the handmade equivalent of the enum-singleton that much more complex. OK, I'm going to have to try writing one of these bad boys myself, and see how I feel in the morning.
Muhammad Khojaye
Ranch Hand

Joined: Apr 12, 2009
Posts: 449

I agree with Ernest. You can easily control instance creation using readResolve method. Infact, Enums are not meant for Singleton.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Questions About Being Static