Why Must Local Variables, Including Primitives, Always Be Initialized in Java

Why must local variables, including primitives, always be initialized in Java?

Basically, requiring a variable to be assigned a value before you read it is a Good Thing. It means you won't accidentally read something you didn't intend to. Yes, variables could have default values - but isn't it better for the compiler to be able to catch your bug instead, if it can prove that you're trying to read something which might not have been assigned yet? If you want to give a local variable a default value, you can always assign that explicitly.

Now that's fine for local variables - but for instance and static variables, the compiler has no way of knowing the order in which methods will be called. Will a property "setter" be called before the "getter"? It has no way of knowing, so it has no way of alerting you to the danger. That's why default values are used for instance/static variables - at least then you'll get a known value (0, false, null etc) instead of just "whatever happened to be in memory at the time." (It also removes the potential security issue of reading sensitive data which hadn't been explicitly wiped.)

There was a question about this very recently for C#... - read the answers there as well, as it's basically the same thing. You might also find Eric Lippert's recent blog post interesting; it's at least around the same area, even though it has a somewhat different thrust.

Java: Why am I required to initialize a primitive local variable?

Because it's a local variable. This is why nothing is assigned to it :

Local variables are slightly different; the compiler never assigns a
default value to an uninitialized local variable. If you cannot
initialize your local variable where it is declared, make sure to
assign it a value before you attempt to use it. Accessing an
uninitialized local variable will result in a compile-time error.

Edit: Why does Java raise this compilation error ?
If we look at the IdentifierExpression.java class file, we will find this block :

...
if (field.isLocal()) {
LocalMember local = (LocalMember)field;
if (local.scopeNumber < ctx.frameNumber && !local.isFinal()) {
env.error(where, "invalid.uplevel", id);
}
if (!vset.testVar(local.number)) {
env.error(where, "var.not.initialized", id);
vset.addVar(local.number);
}
local.readcount++;
}
...

As stated (if (!vset.testVar(local.number)) {), the JDK checks (with testVar) if the variable is assigned (Vset's source code where we can find testVar code). If not, it raises the error var.not.initialized from a properties file :

...
javac.err.var.not.initialized=\
Variable {0} may not have been initialized.
...

Source

Why local variable MUST be initialized and why instance variables MUST NOT be initialized before using?

As I know,

  • Instance variable: will be initial at the run time when class initial and default of instance variable is null => instance variable will error at run time.
  • Local variable: Unlike class and instance variables, a local variable is fussy about where you position the declaration for it: You must place the declaration before the first statement that actually uses the variable. => local variable error with syntax error.

    ref: Local variable in java

Why must local variables, including primitives, always be initialized in Java?

Basically, requiring a variable to be assigned a value before you read it is a Good Thing. It means you won't accidentally read something you didn't intend to. Yes, variables could have default values - but isn't it better for the compiler to be able to catch your bug instead, if it can prove that you're trying to read something which might not have been assigned yet? If you want to give a local variable a default value, you can always assign that explicitly.

Now that's fine for local variables - but for instance and static variables, the compiler has no way of knowing the order in which methods will be called. Will a property "setter" be called before the "getter"? It has no way of knowing, so it has no way of alerting you to the danger. That's why default values are used for instance/static variables - at least then you'll get a known value (0, false, null etc) instead of just "whatever happened to be in memory at the time." (It also removes the potential security issue of reading sensitive data which hadn't been explicitly wiped.)

There was a question about this very recently for C#... - read the answers there as well, as it's basically the same thing. You might also find Eric Lippert's recent blog post interesting; it's at least around the same area, even though it has a somewhat different thrust.

Java variable initialization different ways of handling?

From the Oracle documentation on Java Primitive Data Types:

Local variables are slightly different; the compiler never assigns a
default value to an uninitialized local variable. If you cannot
initialize your local variable where it is declared, make sure to
assign it a value before you attempt to use it. Accessing an
uninitialized local variable will result in a compile-time error.

So this is an interesting nuance. If a primitive type variable is locally declared, you must specify a value for it.

Explicit initialization of primitives

Using default values produced by Java is absolutely OK, you do not need to explicitly initialize instance or static fields of your class. Java Language Specification requires this, so any implementation of the language must comply. In other words, your code would remain 100% portable if you use default values of member variables. This applies to both primitive and reference types (the later are initialized with null).

See Java Language Specification, page 81, for more details.

4.12.5 Initial Values of Variables

Every variable in a program must have a value before its value is used:
- Each class variable, instance variable, or array component is initialized with a
default value when it is created

The only case where you must provide explicit initialization is when you declare local variables:

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

However, since failure to initialize a local is a compile-time error, the compiler will pinpoint every missing initialization before you can run your program.

why is it a bad practise to not initialize primitive fields in a class?

ALL instance variables are initialized. If you don't specify a value, the default value is used.

Who says it's bad practice to not initialize instance variables? I tend not to initialize them unless it's to a non-default value, but it's not a big deal either way. It's about readability and reducing "code noise" improves readability. Useless initializing is code noise IMHO.



Related Topics



Leave a reply



Submit