简体   繁体   中英

Unexpected behaviour with Java initialization

Note: I am well aware that initializing it fixes the problem; I just assumed the compiler would follow the execution path and see that foo would actually be initialized at the point where it suggests it 'may' not be.

My initial assumption would be that if the length was never over 3, I would never need to allocate memory for it to be used.

This will never be used in production, I am simply curious

See the following example: -

List<String> foo;

int length = 5;

if (length > 3)
{
    foo = new ArrayList<String>();
}

if (length > 4)
{
    foo.add("bar");
}

Why is this causing the following to be displayed?

The local variable foo may not have been initialized

Surely following the branches, there is never a case whereby foo is not initialized. I know that if I were to do: -

List<String> foo = null;

there would be no compilation problems, but why do I need to do this?

The compiler can't be sure that you're first if block will be entered. If it doesn't, then foo will stay uninitialized. You can't call add on an uninitialized variable,. You can help the compiler by making length final. The compiler will then know, that the first if block will be executed.

final int length = 5;

Local variables needs to be initialized before using it anywhere else because it will not be initialized by default .What if the if() is not true ?

if (length > 3)
{
    foo = new ArrayList<String>();
}

The compiler can't tell if the condition will be true.

A local variable (§14.4, §14.13) 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 by the compiler using the rules for definite assignment

As @jlordo pointed out making the length as final will resolve the compilation error , because at the compile time itself the compiler knows that the value of length will always be 5 and hence the condition length>3 is always true so the local variable will be initialized.

Because a local instance is not initialized by default, unlike class or object instances.

From the Java Language Specification :

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 by the compiler using the rules for definite assignment (§16).

The default values:

For type byte, the default value is zero, that is, the value of (byte)0.
For type short, the default value is zero, that is, the value of (short)0.
For type int, the default value is zero, that is, 0.
For type long, the default value is zero, that is, 0L.
For type float, the default value is positive zero, that is, 0.0f.
For type double, the default value is positive zero, that is, 0.0d.
For type char, the default value is the null character, that is, '\u0000'.
For type boolean, the default value is false.
For all reference types (§4.3), the default value is null. 

This happens because foo is initialized in a branch. So the compiler isn't sure if foo will be initialized or not.

Instance and class variables are initialized to null or 0 values. But local variables are not. So you must have to initialize the local variables before using it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM