Parenthesized "this" and final fields
Alex Buckley
alex.buckley at oracle.com
Thu Jun 7 19:01:04 UTC 2018
On 6/7/2018 5:37 AM, Maurizio Cimadamore wrote:
> The examples you report fall in the 'forward reference' category, which
> is dealt with in this section:
>
> 8.3.3. Restrictions on Field References in Initializers
>
> Here, basically, the spec says that unqualified forward references are
> disallowed, for both statics and instance fields.
>
> This means (surprisingly, and I've been surprised by this many times) -
> that:
>
> class Foo {
> int x = y;
> int y = 2;
> }
>
> is illegal, but this is legal
>
> class Foo {
> int x = this.y;
> int y = 2;
> }
>
> (similar examples can be constructed for static fields, just replace
> 'this' with 'Foo').
>
> So, when a qualified reference is used, as in your example, all bets are
> off - the compiler doesn't check anything - you are pulling the plug on
> static checking, in a way.
>
> That covers your first example.
Frankly, allowing the forward reference in `int x = this.y;` is as silly
as allowing access to the blank final field in `final int x; int y =
this.x;`. We eventually prohibited the blank final access, and we ought
to prohibit the forward reference too, by having 8.3.3 adopt the "or
simple name qualified by this" clause seen in 16.0.
Still, right now, JLS10 says that Tagir's first example, with
parentheses removed, should compile, but he says it doesn't:
class Unassigned {
final int x = this.y + 1;
final int y = this.x + 1;
}
> As for the second example, I think the point of contention is all around
> this sentence in the spec:
>
> > Throughout the rest of this chapter, we will, unless explicitly
> stated otherwise, write V to represent a local variable or blank |final|
> field which is in scope (§6.3
> <https://docs.oracle.com/javase/specs/jls/se10/html/jls-6.html#jls-6.3>). Likewise,
> we will use |a|, |b|, |c|, and |e| to represent expressions, and S and T
> to represent statements. We will use the phrase "|a| is V" to mean that
> |a| is either the simple name of the variable V, or V's simple name
> qualified by |this| (ignoring parentheses). We will use the phrase "|a|
> is not V" to mean the negation of "|a| is V".
>
> What does this mean? I see many different ways to add parenthesis to a
> qualified this reference:
>
> (this).x = value //as in your example
> (this.x) = value
>
> I trust that the spec here means that every parenthesis should be
> dropped; which would suggest we have a bug here.
Right. The "ignoring parentheses" clause ought to appear in 16.0 too.
Alex
More information about the compiler-dev
mailing list