It's defined this way in the Java Language Specification:
Chapter 16. Definite Assignment
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.
Where the term "blank final
field" refers to a final field with no value or initializer, and "definitely assigned" means that the field will be assigned to no matter what:
The idea behind definite assignment is that an assignment to the local variable or blank final
field must occur on every possible execution path to the access. Similarly, the idea behind definite unassignment is that no other assignment to the blank final variable is permitted to occur on any possible execution path to an assignment.
Aside from throwing an error by specification, there's logical reasoning behind the decision. There's no point in having a default value for a blank final
field. In your case, the blank final
is an integer, and it would just be given 0 and you wouldn't be able to change it. What would the use of the variable be?
Also, if a final
variable is not explicitly given a default value, why not initialize it in the first place? You can't reassign to it later since a default value would already be given, so why not initialize it now?