Walter Bright escribió:
Ary Borenszweig wrote:
Walter Bright escribió:
Ary Borenszweig wrote:
Walter Bright escribió:
Ary Borenszweig wrote:
It's not like that. They don't require you to initialize a
variable in it's initializer, but just before you read it for the
fist time. That's very different.
The only way to do that 100% reliably is to instrument the running
code.
Java does it on compile time.
Java is a severely constrained language. Even so, how does it do with
this:
Foo f;
if (x < 1) f = new Foo(1);
else if (x >= 1) f = new Foo(2);
f.member();
Whenever there are branches in code and a variable still doesn't have
a value at that point:
- if all branches assign a value to that variable, from now on the
variable has a value
- if not, at then end of the branches the variable still doesn't have
a value
That rule gets the wrong answer in the above case. Consider that in
order to get where you want to go with this, the flow analysis has to
always work, not most of the time work. Otherwise you get bug reports
with phrases like "seems to", "sometimes", "somehow", "I can't figure it
out", "I can't reproduce the problem", etc.
Here's another lovely case:
Foo f;
if (x < 1) f = new Foo();
... lots of code ...
if (x < 1) f.member();
The code is quite correct and bug-free, but flow analysis will tell you
that f in f.member() is "possibly uninitialized".
That's exactly the example of a code with a possible bug that'll get an
null pointer access. Imagine in "... lots of code ..." you use f and the
compiler complains. But you are sure "x < 1" will be true! Then you need
to add an else and some assert(false) or throw an exception and that's it.
If the second condition is "if (x >= 1)" and in the next line you use f,
then yes, you are definitely sure that "f" is initialized if you didn't
touch "x" in "... lots of code ...". Well... not really, if some other
thread changed "x" in the middle of the code, then you are not really
sure about that. So again, it's an error.
If you are really, really sure that this won't happen, you do:
Foo f = null;
and that's it. You make the compiler help you only when you want it to,
and that'll be most of the time.
The same goes with:
Foo f;
bar(&f);
If you are sure that bar will assign a value to f if it doesn't have
one, go ahead and initialize "f" with null.