5

First of all, this question has forward relation to these nice questions:

1) Use of uninitialized final field - with/without 'this.' qualifier

2) Why isn't a qualified static final variable allowed in a static initialization block?

But I will ask it in slightly another angle of view. Just to remember: mentioned questions above were asked about access to final fields using keyword this in Java 7.

In my question there is something similar, but not the same. Well, consider the following code:

public class TestInit {
    final int a;
    {
        // System.out.println(a);   -- compile error
        System.out.println(getA());
        // a = a;                   -- compile error
        a = getA();
        System.out.println(getA());
    }
    private int getA() {
        return a;
    }
    public static void main(String[] args) {
        new TestInit();
    }
}

And output is:

0
0

As you can see there are two unclear things here:

  1. There is another legal way to access non-initialized final field: using its getter.
  2. Should we consider that an assigment a = getA(); as legal for blank final field and that it will always assign to it its default value like for non-final field according to JLS? In other words, should it be considered as expected behaviour?
Community
  • 1
  • 1
Andremoniy
  • 34,031
  • 20
  • 135
  • 241

1 Answers1

0

What you're really running into is the inference ability of the compiler. For your first compiler error, that fails because the compiler definitely knows a is not assigned. Same with the second a=a (you can't assign from a because it's definitely not assigned at that point). The line that works a=getA() is a first, single, definite assignment of a, so that's fine (regardless where the value comes from; the implementation of getA() doesn't matter and isn't assessed at this point).

The method getA() is valid and can return a because the instance initializer has definitely assigned a value to a.

It makes sense to a human looking at it, but it's not an inference built into the compiler. Each block, independently evaluated, is valid.

user1676075
  • 3,056
  • 1
  • 19
  • 26