Parenthesized "this" and final fields

Maurizio Cimadamore maurizio.cimadamore at oracle.com
Thu Jun 7 12:37:40 UTC 2018


(Adding Alex/Dan, question for you at the bottom)

I believe there's some confusion here.

First the bug you mention refers to a bug in DA/DU implementation. DA/DU 
only applies to local variables and blank finals, so you see that your 
examples totally avoid any kind of DA/DU enforcement.

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.

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.

Alex, Dan, could you please comment on this point?

Maurizio

On 07/06/18 11:58, Tagir Valeev wrote:
> Hello!
>
> I've found this issue:
> https://bugs.openjdk.java.net/browse/JDK-8156180
>
> In Java 8 "(this)" expression was not specially handled as qualifier 
> with respect to DA/DU analysis. This issue says to fix the problem. 
> However to me it seems that the problem was fixed only partially. E.g. 
> the following code still compiles in Java 10:
>
> class Unassigned {
>   final int x = (this).y + 1;
>   final int y = (this).x + 1;
> }
>
> While removing parentheses make it failing of course. Also the 
> following code fails:
>
> class Unassigned {
>   final int x;
>
>   Unassigned() {
>     (this).x = 1;
>   }
> }
>
> While removing parentheses make it working. I expect that either 
> parentheses should be allowed everywhere or disallowed everywhere. It 
> was consistent in Java 8 (disallowed everywhere), and now it looks 
> confusing.
>
> What do you think? Does this behavior follow the spec?
>
> With best regards,
> Tagir Valeev.

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.openjdk.java.net/pipermail/compiler-dev/attachments/20180607/e4270486/attachment.html>


More information about the compiler-dev mailing list