7

I am learning linkedlist in Java and I have three files Main.java, List.java and Node.java. When I am doing this, I got a question why should I initialize a local variable which is declared in method and but not class variable which is declared in class.

In the first pic, I declared head as class variable, it doesn't throw any error.

But in the second pic I initialized head as local variable.Now, it throws a error to initialize local variable.

What makes the difference when declared as class variable?

enter image description here

Beginner in Java.

Update: I know how to fix this but I am not clear why Java initializing only class variables by default but not local variables.

Peter O.
  • 32,158
  • 14
  • 82
  • 96
Jagadish Dabbiru
  • 930
  • 9
  • 22
  • 1
    Field variables are initialized by default. This is because those variables need to be accessable as soon as the instance is created, since they are accessable as long as the object is alive. Local variable, however, are only needed when that particular local scope is being executed. If Java were to initialize local vars, they'd either be initialized everytime the scope is executed, or would need to be kept somewhere on the stack. Im sure it's this way for performance reasons – Vince Oct 26 '14 at 18:12
  • 1
    @AndyThomas I don't know why this is being marked as duplicate. He's not asking about the error (I'm sure he understands how to fix). He's asking why it's like this, a question I cannot find on StackOverflow – Vince Oct 26 '14 at 18:15
  • @VinceEmigh - Fair enough, it was a rough match. Re-opening. – Andy Thomas Oct 26 '14 at 18:23
  • Please reformat your question and title to better fit the situation. "why java initializing only class variables by default but not local variables" would be a better title (taken from your update) – Vince Oct 26 '14 at 18:50

4 Answers4

2

Static/Non-static fields that are not primitives, like your Node, are initialized at null by default. Static/Non-static fields that are primitive gets their default values.

There's also another case where some variables are initialized with default: when you instantiate an array. Each cell represents has default value, regarding the type:

  • 0 for int
  • null for Integer
  • etc.

However, in a local method, compiler does not assign default value to local variables.
That's why your IDE warns about: "may not be initialized!".

To understand why, you may be interested in this post.

Community
  • 1
  • 1
Mik378
  • 21,881
  • 15
  • 82
  • 180
2

This is explained rather well by the Java Language Specification (specifically, §4.12.5):

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 (§15.9, §15.10):
  • For all reference types (§4.3), the default value is null.
  • 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).

To expand a bit, §16 goes into the rules for definite assignment, which is at the crux of the reason:

Each local variable (§14.4) and every blank final field (§4.12.4, §8.3.1.2) must have a definitely assigned value when any access of its value occurs.

For every access of a local variable or blank final field x, x must be definitely assigned before the access, or a compile-time error occurs.

Simply put: Java will assign default values to class/instance variables, but will not assign a default value to a local variable. Local variables must be definitely assigned in this manner (either by initialization or assignment), or a compile time error will occur (as you observe).

If you think of it from another angle, when you initialize a class that contains specific fields, you may not want those initialized to a value at first (think JavaBeans). If you're in a code block and you declare a variable, the expectation instead is on the developer to control that object's life cycle right there in the block.

It doesn't make sense to simply declare a variable and attempt to do something with it without assigning a value to it, as the variable doesn't have a value.

Community
  • 1
  • 1
Makoto
  • 104,088
  • 27
  • 192
  • 230
  • 1
    He already knows this. Read the last part of his question EDIT: nvm, it got taken down. But he stated that he understands it must be initialized. Hes just not sure why it's like that – Vince Oct 26 '14 at 18:32
  • I'm not sure what you mean by "he already knows this". The JLS reference wasn't made explicit, and this is **the** reason why you have to initialize a local variable, but you don't have to for an instance variable. – Makoto Oct 26 '14 at 18:33
  • "A local variable must be explicitly given a value before it is used" So thats why a local variables aren't initialized to defaults? That would be the answer if he asked "Why am I getting this error" – Vince Oct 26 '14 at 18:34
  • A bit more information comes in from section 16 of the JLS. I've added it into the answer. – Makoto Oct 26 '14 at 18:39
  • But you don't mention *why*. He understands that a compile-time error will occur, but why does it occur when he doesn't initialize the local variable before using it? One could say "because java works like that, compile-time errors when trying to use an uninitialized local variable", but he's looking for the logical reason. In his update, he says he knows how to fix it; he just doesn't understand why field variables get initialized to defaults and local variables don't – Vince Oct 26 '14 at 18:44
  • Keep in mind, this post got re-opened from being a duplicate. The duplicate states exactly what you are stating now. That's not what he's looking for – Vince Oct 26 '14 at 18:45
  • You're misreading both the answer and the spec. The spec has mandated that local variables must be definitely assigned before any access occurs to them or a compile time error occurs. That's the reason why. The spec also mentions that field/class variables are given an initial default value. I'm not sure what the confusion is; it's as mandated by the spec. – Makoto Oct 26 '14 at 18:45
  • Why does a compile time error occur though? Why aren't local variables assigned to defaults aswell? – Vince Oct 26 '14 at 18:48
0

In the first case java can't know, when you assign the value to the node "head". You could have a call before calling "add" In the second the commands are in the same method and the order of execution is clear.

In every case you should initialize every variable. If I remember right Member variables are initialized to null, but I'm not sure it work out for every jvm

  • *reference* field variables are assigned to null. *primitive* field variables are initialized to their [default values](http://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html) (scroll down to default values) – Vince Oct 26 '14 at 18:18
  • 1
    And this is part of the language specification, not the JVM interpretation of the specification. In fact, a naive JVM might make larger code if you init instance variables explicitly. You are essentially asking the VM to run code for the class before the constructor. It is, IMHO, bad Java form. –  Oct 26 '14 at 18:31
0

For why the language works this way, that's because the favored style is to delay the declaration of local variables until they're first used. Java was designed so that you don't have to declare a variable until the spot where it is first used (unlike, for example, JavaScript, where due to lack of block-level scope and also due to hoisting you're better off declaring the variables at the start of the method or function), so it shouldn't be an issue that local variables don't get a default value.

Also for local variables the idea must have been that there was relatively little value in assigning a default value. Even if I do want to initialize a local variable it's good to be explicit about it.

Of course for instance and class members declare-at-first-use doesn't apply, because there's no telling what could call it. If something isn't assigned it needs to receive a default value.

Nathan Hughes
  • 94,330
  • 19
  • 181
  • 276