<div dir="ltr">Hi Jan,<div><br></div><div>I'm sure it's not a regression, and I agree this behavior is reasonable and nobody writes code like that - just wonder if it follows the spec or if the spec needs to be updated.</div>
<div><br></div><div>I saw this code on a message board where the anonymous class (compiling) was contrasted with the lambda (not compiling). Moreover, it only showed up because, after the update to JDK8, NetBeans suggested the original author to replace the anonymous with a lambda - and the suggestion turned out to be a failure, because after the "translation" the code did not compile anymore.</div>
<div><br></div><div>To me the contrast with the lambda is key here, because it's feels wrong the compiler behaves in two different ways. We all know lambdas and anonymous classes are totally different beasts, but the semantic is the same wrt this situation, while the compiler is inconsistent: it  screws because the blank final can be accessed before being assigned, but only if it's a lambda, not if it's an anonymous, despite the fact that both are instance fields, so can only be leaked before a ctor ends. I think arguing about the lambda machinary and other compiler internals doesn't buy anything to us in this case - I expect an explicit rule here, not reasons why javac might not be wrong in doing this and also might not be wrong in doing that even if the two are opposite behaviors </div>
</div><div class="gmail_extra"><br><br><div class="gmail_quote">2014-04-08 18:37 GMT+02:00 Jan Lahoda <span dir="ltr"><<a href="mailto:jan.lahoda@oracle.com" target="_blank">jan.lahoda@oracle.com</a>></span>:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div class="">On 04/08/2014 02:06 AM, Alex Buckley wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
The question for compiler-dev is not whether the DU/DA analysis within<br>
anonymous classes is reasonable, but whether there's been a regression<br>
in javac. I know Paul and Jan are working on DU/DA analysis at the<br>
moment, maybe they could comment.<br>
</blockquote>
<br></div>
I don't think there is a regression in javac - I was able to compile the provided code with "1.4.2_07" javac. Intuitively, considering the methods declared in the anonymous innerclass to be outside of the expression that contains the new instance expression itself seems reasonable to me. Note that if the access is moved to the initializer of the anonymous class, it is flagged as an error (which makes sense to me).<span class="HOEnZb"><font color="#888888"><br>

<br>
Jan</font></span><div class="HOEnZb"><div class="h5"><br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
Alex<br>
<br>
On 4/7/2014 3:50 PM, Raffaele Sgarro wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Hi Alex,<br>
<br>
In fact, the lambda behavior is correct to me. Why do you think it would<br>
be unreasonable for the anonymous?<br>
<br>
<br>
2014-04-08 0:09 GMT+02:00 Alex Buckley <<a href="mailto:alex.buckley@oracle.com" target="_blank">alex.buckley@oracle.com</a><br>
<mailto:<a href="mailto:alex.buckley@oracle.com" target="_blank">alex.buckley@oracle.<u></u>com</a>>>:<br>
<br>
    I don't believe javac has ever given an error in this case. It would<br>
    be unreasonable to require 'data' to be definitely assigned before<br>
    the body of the anonymous class. OTOH, names in the body of a lambda<br>
    expression are specified as if they appear outside the lambda<br>
    expression, where 'data' would be definitely unassigned, so an error<br>
    is due there.<br>
<br>
    Alex<br>
<br>
<br>
    On 4/7/2014 10:02 AM, Raffaele Sgarro wrote:<br>
<br>
        §16 states:<br>
<br>
        For every access of a local variable or blank final field x, x<br>
        must be<br>
        definitely assigned before the access, or a compile-time error<br>
        occurs.<br>
<br>
        Consider the following code:<br>
<br>
        class  Ideone{<br>
<br>
                 public  interface  Provider{  String  get();  }<br>
<br>
                 public  static  class  Outer{<br>
<br>
                         private  final  String  data;<br>
                         private  final  String  token;<br>
                         private  final  Provider  secretProvider=  new<br>
          Provider()  {<br>
<br>
                                 public  String  get()  {<br>
                                         return  data;<br>
                                 }<br>
                         };<br>
<br>
                         public  Outer()  {<br>
                                 token=  secretProvider.get();<br>
                                 data=  "FOOBAR";<br>
<br>
                         }<br>
<br>
                         public  String  getToken()  {<br>
                                 return  token;<br>
                         }<br>
<br>
                 }<br>
<br>
                 public  static  void  main(String[]  args)  throws<br>
          java.lang.Exception  {<br>
                         Outer outer=  new  Outer();<br>
<br>
                         System.out.println(outer.__<u></u>getToken());  //<br>
        Prints null<br>
                 }<br>
        }<br>
<br>
        Note that if I used a lambda expression, instead, javac would<br>
have<br>
        complained.<br>
<br>
<br>
</blockquote></blockquote>
</div></div></blockquote></div><br></div>