Compiler confused by parenthesized "this" in final fields assignments

Alex Buckley alex.buckley at oracle.com
Sat Jun 9 00:09:54 UTC 2018


On 6/8/2018 10:39 AM, Victor Williams Stafusa da Silva wrote:
> By assign "this" to some other variable and acessing the unitilized
> field of that variable, it becomes easy to defeat the final variable
> initialization check. It can also be defeated by acessing it through a
> method.

Yes, of course.

> The JLS (chapter 16) says:
>
>     Each local variable (§14.4
>     <https://docs.oracle.com/javase/specs/jls/se10/html/jls-14.html#jls-14.4>)
>     and every blank|final|field (§4.12.4
>     <https://docs.oracle.com/javase/specs/jls/se10/html/jls-4.html#jls-4.12.4>,§8.3.1.2
>     <https://docs.oracle.com/javase/specs/jls/se10/html/jls-8.html#jls-8.3.1.2>)
>     must have a/definitely assigned/value when any access of its value
>     occurs.
>
>     An access to its value consists of the simple name of the variable
>     (or, for a field, the simple name of the field qualified by|this|)
>     occurring anywhere in an expression except as the left-hand operand
>     of the simple assignment operator|=|(§15.26.1
>     <https://docs.oracle.com/javase/specs/jls/se10/html/jls-15.html#jls-15.26.1>).
>
>     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.
>
> Saying "must be definitely assigned before the access, or a compile-time
> error occurs" is a very bold statement that is simply unenforceable and
> broken. The chapter 16 details many of the rules when a variable should
> be considered definitely assigned or definitely unassigned, but it
> overlooks those two cases.

I know what you mean, but in:

   private final int y;
   private final AssignBug x = this;
   private final int z = x.y;
   private final int w = getY();

neither `x.y` nor `getY()` is an access according to the definition "An 
access to its value consists of ...". Therefore, there is no requirement 
that `y` be DA before `x.y` or `getY()`, even though a human reader who 
understands aliasing would obviously like `y` to be so.

Alex


More information about the compiler-dev mailing list