Publishing this [Was: Re: Discrepancy in current hour]
On 3/21/2010 3:54 PM, Lew wrote:
[...]
Regardless of "manner of speaking", it is dangerous to use an instance
before it's fully constructed, super, sub and barrel.
Slight topic branch: One of the unpleasant consequences is
that it's unsafe for a constructor to publish a `this' reference.
When I was a Javanewbie I sometimes wrote classes that maintained
collections of all their instances, thus (genericized for current
audiences, although generics weren't around in my newbie days):
class Wotsit {
private static final Set<Wotsit> universe
= new HashSet<Wotsit>();
Wotsit(...) {
...
universe.add(this);
}
...
}
I later learned that this is a Bad Thing, because if another
thread traverses the contents of `universe' it could come across
a Wotsit (or Wotsit subclass) that wasn't yet fully operational.
The only way I know of to maintain such a collection safely
is to hide the constructor and make folks use a factory method:
class Dingbat {
private static final Set<Dingbat> universe
= new HashSet<Dingbat>();
private Dingbat(...) {
...
}
static Dingbat newInstance(...) {
Dingbat edith = new Dingbat(...);
universe.add(edith);
return edith;
}
...
}
This has the unfortunate side-effect that Dingbat cannot be
subclassed, because of the private constructor. Yet if you
make the constructor anything other than private, there's a
risk that someone will do `new Dingbat()' and `universe' will
be incomplete.
How do others deal with this? Give up on "all instances"
collections? Live with effectively-final classes? Document
the living daylights out of it and hope for the best? Or is
there something niftier that can be done?
--
Eric Sosman
esosman@ieee-dot-org.invalid