Christian Pontesegger wrote On 05/19/06 17:19,:
> Hi all,
>
[quoted text clipped - 33 lines]
> constructor is called or an error when trying to access a member which
> isn't properly initialized.
Initializing all members before calling the constructor
is a non-starter. Conceptually, all those initializations
are magically inserted at the start of every constructor in
the class -- indeed, if you disassemble the byte code for a
class with just one constructor, you'll see that the compiler
does exactly that. Member initialization is part of instance
construction.
Detecting non-initialization at run time would require a
way of tagging the uninitialized data, and maintaining and
testing the tag on each access. That sort of thing would be
pretty expensive[*] -- and besides, it wouldn't change the
behavior of your example! Your problem isn't failure to
initialize, but double initialization.
[*] I recall a long-ago system that managed to do this.
All variable references were indirect through a symbol table
that contained a pointer to the actual memory location where
the data lived. As initialized, all the pointers aimed one
byte too high; if you used the pointer as it stood, you'd get
a bad-alignment trap from the hardware. But when a variable
was written, the code first cleared the low-order bit of the
pointer in the table, so all subsequent references found a
properly-aligned pointer. This was probably the cheapest
uninitialized-variable catcher I've ever seen, yet it doubled
the cost of every read and tripled the cost of every write.
> Now I know how to get my intended behavior, just don't initialize foo =
> "0" and this program will return "5" as expected (at least by me).
>
> But is this behavior mentioned above a design problem or is it even
> useful and I can't see the meaning of it?
The "design problem," I think, is the double initialization
of foo. If you want to initialize it at the point of declaration
then go ahead and do so -- but don't turn around and re-initialize
it in init(). If you want to rely on init(), don't initialize in
the declaration. Choose one way or the other but not both.
Another way to view things is to note that you've violated
one of the Big Rules: Never let a constructor call an overridable
method on the object being constructed. The reason for the
prohibition is to avoid exactly the sort of situation you've run
into here, where an overriding method gets its hands on an
incompletely initialized object.

Signature
Eric.Sosman@sun.com
> Hi all,
>
[quoted text clipped - 42 lines]
> thanks
> Christian Pontesegger
Here is another example that demonstrates your observation:
http://jqa.tmorris.net/GetQAndA.action?qids=10&showAnswers=true
You are simply observing one of the many flaws of behaviour inheritance -
which implies some knowledge about the future.
http://contractualj.com/ "All classes are declared final. Concrete behaviour
inheritance is not permitted."
--
Tony Morris
http://tmorris.net/