Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why attempt to print uninitialized variable does not always result in an error message

Some may find it similar to the SO question Will Java Final variables have default values? but that answer doesn't completely solve this, as that question doesn't directly print the value of x within instance initializer block.

The problem arises when I try to print x directly inside the instance initializer block, while having assigned a value to x before the end of the block :

Case 1

class HelloWorld {      final int x;      {         System.out.println(x);         x = 7;         System.out.println(x);         }      HelloWorld() {         System.out.println("hi");     }      public static void main(String[] args) {         HelloWorld t = new HelloWorld();     } } 

This gives a compile time error stating that variable x might not have been initialized.

$ javac HelloWorld.java HelloWorld.java:6: error: variable x might not have been initialized         System.out.println(x);                            ^ 1 error 

Case 2

Instead of directly printing, I am calling a function to print:

class HelloWorld {      final int x;      {         printX();         x = 7;         printX();     }      HelloWorld() {         System.out.println("hi");     }      void printX() {         System.out.println(x);     }      public static void main(String[] args) {         HelloWorld t = new HelloWorld();     } } 

This compiles correctly and gives output

0 7 hi 

What is the conceptual difference between the two cases?

like image 562
Ashwani Kumar Rahul Avatar asked Nov 30 '15 09:11

Ashwani Kumar Rahul


People also ask

What happens if you print an uninitialized variable?

There is no "result of undefined behaviour". The behaviour is undefined.

Will we get an error message if we display an uninitialized variable?

An uninitialized variable has an undefined value, often corresponding to the data that was already in the particular memory location that the variable is using. This can lead to errors that are very hard to detect since the variable's value is effectively random, different values cause different errors or none at all.

What happens if you print an uninitialized variable in Java?

This gives a compile time error stating that variable x might not have been initialized.

What will happen if you try to access an uninitialized local variable?

There will be no default values or ability to run the code. It will be a compile time error and your code won't run. If the variables were class fields they would get default values for certain types or null otherwise.


1 Answers

In the JLS, §8.3.3. Forward References During Field Initialization, its stated that there's a compile-time error when:

Use of instance variables whose declarations appear textually after the use is sometimes restricted, even though these instance variables are in scope. Specifically, it is a compile-time error if all of the following are true:

  • The declaration of an instance variable in a class or interface C appears textually after a use of the instance variable;

  • The use is a simple name in either an instance variable initializer of C or an instance initializer of C;

  • The use is not on the left hand side of an assignment;

  • C is the innermost class or interface enclosing the use.

The following rules come with a few examples, of which the closest to yours is this one:

class Z {     static int peek() { return j; }     static int i = peek();     static int j = 1; } class Test {     public static void main(String[] args) {         System.out.println(Z.i);     } } 

Accesses [to static or instance variables] by methods are not checked in this way, so the code above produces output 0, because the variable initializer for i uses the class method peek() to access the value of the variable j before j has been initialized by its variable initializer, at which point it still has its default value (§4.12.5 Initial Values of Variables).

So, to summarize, your second example compiles and executes fine, because the compiler does not check if the x variable was already initialized when you invoke printX() and when printX() actually takes place at Runtime, the x variable will be assigned with its default value (0).

like image 138
Konstantin Yovkov Avatar answered Oct 14 '22 23:10

Konstantin Yovkov