6

It is a well know fact that in Java one needs to initialize a local variable before using it (cf. JLS)

A local variable (§14.4, §14.14) must be explicitly given a value before it is used, by either initialization (§14.4) or assignment (§15.26), in a way that can be verified using the rules for definite assignment (§16).

Otherwise one gets a compiler error:

The local variable result may not have been initialized.

What is the rational for this design decision? Why does the compiler not automatically convert a declaration (e.g. int x, double y, String foo, etc.) to a definition initialized with some default value (0, 0.0, null)? Are there any drawbacks of doing so?

Micha Wiedenmann
  • 19,979
  • 21
  • 92
  • 137

3 Answers3

6

The drawback is that the default value may not be what you want - you may have just forgotten to initialise your local variable, and using a default value could then cause an exception (or worse, just run anyway creating some hard to track down bug.)

Forcing a compiler error in this case makes sure you correct the problem and explicitly assign it to whatever you want it to be.

The same argument could be applied to fields, but it's much harder (and technically impossible in every case) to check that they're assigned a value before that value is read, since they could be accessed or written to from anywhere. Ergo, using defaults in this case rather than enforcing this rule is the only sensible approach.

Michael Berry
  • 70,193
  • 21
  • 157
  • 216
  • 2
    Then what is the difference with instance variables, when they get default value? Here you also may face the "the default value may not be what you want - you may have just forgotten to initialize ..." situation. – sergeyan Nov 29 '13 at 10:45
  • @sergeyan The reason is a practical one - see the edit. – Michael Berry Nov 29 '13 at 10:52
0

Just to illustrate berry words.

int x;
float y;

y = 42/x;

String name;

print("Hello " + name);

Sad but those are among the most common mistakes on languages that don't enforce that policy. Remember default values can be different for each variable that's why it was left to the developer to set them.

Andrei Nicusan
  • 4,555
  • 1
  • 23
  • 36
jean
  • 4,159
  • 4
  • 31
  • 52
0

Adding to the @berry120 answer - on the difference between fields and variables.

Not initialized for variables

The behaviour of 'not initialized' state is almost the same as of a final field or variable, except that one may reassign a value (I'll reference it as a 'final behaviour'). So it makes you not to forget to initialize it in a branches like this:

int x;

if(condition1){
    x = 10;
} else
if(condition2){
    if( condition3 ){
        x = 20;
    }   // else branch is missing here
} else {
    x = 40;
}

So the compiler will hint me with an initialization error here. Why not to use final for the same purpose and have a default value for the var? More typing & verbosity + I may want to reassign to this var.

Default values for fields

I think that having a default value is preferred for instance variables, because initializing variables with 'final behaviour' could be a real pain for a class with many constructors. And when you sub-class this class and/or use circular references it could become a real pain... or a puzzle: How to initialize a circular dependency (final fields referencing each other)?.

So having a 'The result may not have been initialized' for an instance field seems impractical.

Community
  • 1
  • 1
Andrey Chaschev
  • 16,160
  • 5
  • 51
  • 68