[BUG] Missing error? blank final may not have been initialized

Raffaele Sgarro raffaelesgarro at gmail.com
Tue Apr 8 21:24:30 UTC 2014


Hi Jan,

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.

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.

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


2014-04-08 18:37 GMT+02:00 Jan Lahoda <jan.lahoda at oracle.com>:

> On 04/08/2014 02:06 AM, Alex Buckley wrote:
>
>> The question for compiler-dev is not whether the DU/DA analysis within
>> anonymous classes is reasonable, but whether there's been a regression
>> in javac. I know Paul and Jan are working on DU/DA analysis at the
>> moment, maybe they could comment.
>>
>
> 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).
>
> Jan
>
>
>
>> Alex
>>
>> On 4/7/2014 3:50 PM, Raffaele Sgarro wrote:
>>
>>> Hi Alex,
>>>
>>> In fact, the lambda behavior is correct to me. Why do you think it would
>>> be unreasonable for the anonymous?
>>>
>>>
>>> 2014-04-08 0:09 GMT+02:00 Alex Buckley <alex.buckley at oracle.com
>>> <mailto:alex.buckley at oracle.com>>:
>>>
>>>     I don't believe javac has ever given an error in this case. It would
>>>     be unreasonable to require 'data' to be definitely assigned before
>>>     the body of the anonymous class. OTOH, names in the body of a lambda
>>>     expression are specified as if they appear outside the lambda
>>>     expression, where 'data' would be definitely unassigned, so an error
>>>     is due there.
>>>
>>>     Alex
>>>
>>>
>>>     On 4/7/2014 10:02 AM, Raffaele Sgarro wrote:
>>>
>>>         §16 states:
>>>
>>>         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.
>>>
>>>         Consider the following code:
>>>
>>>         class  Ideone{
>>>
>>>                  public  interface  Provider{  String  get();  }
>>>
>>>                  public  static  class  Outer{
>>>
>>>                          private  final  String  data;
>>>                          private  final  String  token;
>>>                          private  final  Provider  secretProvider=  new
>>>           Provider()  {
>>>
>>>                                  public  String  get()  {
>>>                                          return  data;
>>>                                  }
>>>                          };
>>>
>>>                          public  Outer()  {
>>>                                  token=  secretProvider.get();
>>>                                  data=  "FOOBAR";
>>>
>>>                          }
>>>
>>>                          public  String  getToken()  {
>>>                                  return  token;
>>>                          }
>>>
>>>                  }
>>>
>>>                  public  static  void  main(String[]  args)  throws
>>>           java.lang.Exception  {
>>>                          Outer outer=  new  Outer();
>>>
>>>                          System.out.println(outer.__getToken());  //
>>>         Prints null
>>>                  }
>>>         }
>>>
>>>         Note that if I used a lambda expression, instead, javac would
>>> have
>>>         complained.
>>>
>>>
>>>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.openjdk.java.net/pipermail/compiler-dev/attachments/20140408/4c1d882c/attachment-0001.html>


More information about the compiler-dev mailing list