Constructor or getInstance() method

Y

yzzzzz

Hi,

In the Java librairies there are many classes that can be built either
by using the constructor method (Foo a = new Foo()) or by calling a
static getInstance() method (Foo a = Foo.getInstance()).

Usually both have arguments, and often both are overloaded.

I was wondering if these 2 ways of creating a new object are equivalent,
or why and when I should use one way or the other. I usually overload my
constructors a lot, but it may be simpler to do a getInstance() method
instead. What are the advantages of each way?

Thanks.
 
T

Tor Iver Wilhelmsen

yzzzzz said:
I was wondering if these 2 ways of creating a new object are
equivalent,

They are not: A constructor is used to create new objects (in a
relatively strict way) and must either return a new object or throw an
exception. The other way - a factory method - may or may not call a
constructor, and can handle errors/exceptions in ways that
constructors cannot - or aren't supposed to. For instance, it could
return null until an object was available.
 
R

Ryan Stewart

yzzzzz said:
Hi,

In the Java librairies there are many classes that can be built either by
using the constructor method (Foo a = new Foo()) or by calling a static
getInstance() method (Foo a = Foo.getInstance()).
There are? Can you name a few? I'm aware of only one, and I don't really know if
it's that way on purpose or if it was just poor design. I don't know of any good
reasons to have both public constructors and factory methods.
 
Y

Yakov Fain

I was wondering if these 2 ways of creating a new object are equivalent,
or why and when I should use one way or the other. I usually overload my
constructors a lot, but it may be simpler to do a getInstance() method
instead. What are the advantages of each way?
If you have a static method getInstance(), constructor of this class
must be private. This is used when you want to control the number of
the instances of the object returned by getInstance().

One of the examples is a Singleton pattern and getInstance() ensures
that only one instance of the class will exist at any time. If this
class had a public constructor, multiple instances could have been
created
 
J

John C. Bollinger

Yakov said:
If you have a static method getInstance(), constructor of this class
must be private. This is used when you want to control the number of
the instances of the object returned by getInstance().

One of the examples is a Singleton pattern and getInstance() ensures
that only one instance of the class will exist at any time. If this
class had a public constructor, multiple instances could have been
created

You are mixing two completely different things. It is true that correct
implementation of the Singleton pattern requires the singleton class to
have a private constructor, but that doesn't have any relevance to the
question of factory methods in general. Consider abstract factories,
which often have a static getInstance() method (or equivalent) for
obtaining an instance of an appropriate concrete implementation, but
which must have an accessible constructor so that there can _be_
concrete implementations.


John Bollinger
(e-mail address removed)
 
E

Eric Sosman

Ryan said:
There are? Can you name a few?

java.lang.Boolean
java.lang.Byte
java.lang.Double
java.lang.Float
java.lang.Integer
java.lang.Long
java.math.BigDecimal
java.math.BigInteger
java.util.Calendar

.... and probably others. (An oddity: Why is java.lang.Character
not on this list?)
I'm aware of only one, and I don't really know if
it's that way on purpose or if it was just poor design. I don't know of any good
reasons to have both public constructors and factory methods.

Joshua Bloch suggests a few in "Effective Java." My
copy is at home, so these few are from (hazy) memory:

- Efficiency: A constructor must produce a brand-new
object, whereas a factory method can (sometimes) re-use
an existing object. `new Boolean(false)' must create
a brand-new Boolean, whereas `Boolean.valueOf(false)'
can just return the Boolean.FALSE object.

- Flexibility: A constructor must produce an object of
the stated class, whereas a factory method is free to
return an instance of a subclass. (Conceded: In this
sort of situation, it might be more usual to expose only
the factory methods and hide the constructors.)

- Clarity: Constructors are nameless, so if you want to
provide multiple constructors you must give them different
argument signatures. Factory methods have names, so they
can be distinguished even if their signatures are identical.
Thing of a complex-number class providing a constructor
`Complex (double x, double y)' for numbers in Cartesian
form, plus `static Complex polar(double rho, double theta)'
as a factory method for numbers in polar coordinates. (For
symmetry, `static Complex cartesian(double x, double y)'
would probably be there, too.)

Disclaimer: I myself am a non-guru (but not, I hope, an
anti-guru), and cannot argue the merits of these reasons except
at a superficial level.
 
R

Ryan Stewart

Eric Sosman said:
java.lang.Boolean
java.lang.Byte
java.lang.Double
java.lang.Float
java.lang.Integer
java.lang.Long
java.math.BigDecimal
java.math.BigInteger
java.util.Calendar

... and probably others. (An oddity: Why is java.lang.Character
not on this list?)
Minus java.util.Calendar (it has protected constructors) and plus
java.lang.Short, yes. I was trying to think of getInstance methods, not factory
methods in general, and since I never use the factory methods of those
classes... That is something I've wondered about in the past, now that I realize
it. The only thing you could really do with java.lang.Character is let it take a
String, and that's probably asking for trouble. I suppose you could also take
ints and a character encoding to interpret it.
Joshua Bloch suggests a few in "Effective Java." My
copy is at home, so these few are from (hazy) memory:

- Efficiency: A constructor must produce a brand-new
object, whereas a factory method can (sometimes) re-use
an existing object. `new Boolean(false)' must create
a brand-new Boolean, whereas `Boolean.valueOf(false)'
can just return the Boolean.FALSE object.
I wouldn't consider this a good reason to have both. Especially in the case of
Boolean, I would argue that a public constructor is bad.
- Flexibility: A constructor must produce an object of
the stated class, whereas a factory method is free to
return an instance of a subclass. (Conceded: In this
sort of situation, it might be more usual to expose only
the factory methods and hide the constructors.)
My thoughts exactly.
- Clarity: Constructors are nameless, so if you want to
provide multiple constructors you must give them different
argument signatures. Factory methods have names, so they
can be distinguished even if their signatures are identical.
Thing of a complex-number class providing a constructor
`Complex (double x, double y)' for numbers in Cartesian
form, plus `static Complex polar(double rho, double theta)'
as a factory method for numbers in polar coordinates. (For
symmetry, `static Complex cartesian(double x, double y)'
would probably be there, too.)
That does make some sense, though for ease of reading and maintenance in this
situation, I would go with all factory methods, because who is really going to
go in looking for a constructor to create objects one way and a method to create
them another? It it's inconsistent and illogical.
 
P

Patricia Shanahan

Ryan said:
I wouldn't consider this a good reason to have both. Especially in the case of
Boolean, I would argue that a public constructor is bad.

Consider not breaking existing programs as reason for
keeping the constructor.

Boolean.valueOf(boolean) is "Since 1.4". Boolean(boolean)
was in Java 1.0.2.

I suspect that a lot of classes with factory methods for
efficiency may also have public constructors for backwards
compatibility.

Patricia
 
R

Ryan Stewart

Patricia Shanahan said:
Consider not breaking existing programs as reason for
keeping the constructor.

Boolean.valueOf(boolean) is "Since 1.4". Boolean(boolean)
was in Java 1.0.2.

I suspect that a lot of classes with factory methods for
efficiency may also have public constructors for backwards
compatibility.
Certainly there's a lot of things around for reasons of backwards compatibility,
but that doesn't mean the Boolean constructors couldn't be deprecated (at least
in the documentation).
 
J

Joona I Palaste

Ryan Stewart said:
I wouldn't consider this a good reason to have both. Especially in the case of
Boolean, I would argue that a public constructor is bad.

I agree about Boolean. Unlike all the other primitive types and their
wrapper classes, Boolean has even *conceptually* a finite number of
values, and a small set it is too. So creating new Boolean objects is a
waste of space and time, because the entire conceptual model can only
support *two* Boolean objects with different semantics.
 
T

Tom McGlynn

Joona said:
I agree about Boolean. Unlike all the other primitive types and their
wrapper classes, Boolean has even *conceptually* a finite number of
values, and a small set it is too. So creating new Boolean objects is a
waste of space and time, because the entire conceptual model can only
support *two* Boolean objects with different semantics.
There are only two distinct values, but a boolean represents a decision
and I may want to indicate that even though two booleans have the
same value they represent distinct decisions.

E.g., Suppose I have a bunch of settings. The global default
can be either on or off, and the user can override any individual setting.
Now you want to know which settings the user has explicitly set.
If I created a new Boolean for each user selection then
one just has
if (userSetting == defaultSetting) ...
If I had to reuse Booleans, then I'd be out of luck when the user
explictly set something to be the same as the default since the
two objects would be the same.

Of course I could wrap a Boolean in another class but since that seems
a little silly to me since the Boolean itself just wraps the primitive.

Regards,
Tom McGlynn
 
J

John C. Bollinger

Tom said:
Joona I Palaste wrote:
There are only two distinct values, but a boolean represents a decision
and I may want to indicate that even though two booleans have the
same value they represent distinct decisions.

E.g., Suppose I have a bunch of settings. The global default
can be either on or off, and the user can override any individual setting.
Now you want to know which settings the user has explicitly set.
If I created a new Boolean for each user selection then
one just has
if (userSetting == defaultSetting) ...
If I had to reuse Booleans, then I'd be out of luck when the user
explictly set something to be the same as the default since the
two objects would be the same.

A Boolean does *not* "represent a decision", it represents a truth
value. The result of a binary decision can be considered as a truth
value (the value of the proposition "the first option was chosen"), so
certainly you can *use* Booleans as you describe. That is by no means
central to the class definition, however, and so is not relevant to the
question of how many and which instances _should_ be available.

I'd argue that the approach you describe is a bit thin anyway. For
instance, what is the significance of (userSetting1 == userSetting2)?
You are suggesting modeling a tristate value (true / false / default)
via two Boolean objects, and it would be better to use one. One
alternative would be to represent reliance on the default value with a
null reference instead of with a reference to a specific default value
Boolean. You then get your tristate with values Boolean.TRUE,
Boolean.FALSE, and null. Another approach would be to use a
hierarchical collection of settings with automatic fallback, along the
lines of a Properties or ResourceBundle.
 
T

Tilman Bohn

In message <[email protected]>,
Tom McGlynn wrote on Wed, 09 Feb 2005 10:12:49 -0500:

[...]
E.g., Suppose I have a bunch of settings. The global default
can be either on or off, and the user can override any individual setting.
Now you want to know which settings the user has explicitly set.
If I created a new Boolean for each user selection then
one just has
if (userSetting == defaultSetting) ...

Am I the only one who'd consider this dangerous practice? This is just
waiting for a maintenance programmer to make client code dispense with
creating those supposedly `superfluous' objects, at which point this
scheme will break. IMO, you better have _copious_ documentation on this
misuse of object identity with these (to the average maintainer)
unexpected semantics... But as I said, maybe it's just me.
 
R

Ryan Stewart

Tilman Bohn said:
In message <[email protected]>,
Tom McGlynn wrote on Wed, 09 Feb 2005 10:12:49 -0500:

[...]
E.g., Suppose I have a bunch of settings. The global default
can be either on or off, and the user can override any individual setting.
Now you want to know which settings the user has explicitly set.
If I created a new Boolean for each user selection then
one just has
if (userSetting == defaultSetting) ...

Am I the only one who'd consider this dangerous practice? This is just
waiting for a maintenance programmer to make client code dispense with
creating those supposedly `superfluous' objects, at which point this
scheme will break. IMO, you better have _copious_ documentation on this
misuse of object identity with these (to the average maintainer)
unexpected semantics... But as I said, maybe it's just me.
No, I'd consider that dangerous too. Typically the first thing I do when I see a
"new Boolean(...)" in code is replace it with an appropriate constant or method
call.
 
T

Tor Iver Wilhelmsen

Tom McGlynn said:
E.g., Suppose I have a bunch of settings. The global default
can be either on or off, and the user can override any individual setting.
Now you want to know which settings the user has explicitly set.

Do what Borland did, and make a tristate class/enum with TRUE, FALSE
and DEFAULT. Then use some lookup method like this (here placed as
instance method in Setting class, with static import of Tristate):

public boolean value(Tristate userValue) {
if (userValue == DEFAULT)
return default();
else
return (userValue == TRUE);
}

(Borland, in their infinite wisom, mucked things up by adding a second
tristate class with YES, NO and MAYBE or something like that.)
Of course I could wrap a Boolean in another class but since that
seems a little silly to me since the Boolean itself just wraps the
primitive.

It's not silly when the two-state primitive (and its wrapper class)
clearly is insufficient for your needs. You are trying to force a
suqare peg into a round hole - stop that!
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top