JLS - "anywhere within" static initializer

Alex Buckley alex.buckley at oracle.com
Fri Oct 18 19:21:53 UTC 2019


On 8/17/2018 11:35 AM, Kay, Andrew (Research Student) wrote:
> I've noticed something slightly misleading in the JLS, section 8.7 
> (Static Initializers):
> 
> It is a compile-time error if a return statement> (§14.17) appears 
> anywhere within a static initializer.
...
> This could be resolved by adding something like "…anywhere within a 
> static initializer, unless it appears within a local class 
> declaration contained in that static initializer". There are at least
> two more cases which should be permitted - anonymous class 
> declarations, and return statements in lambda body blocks.

/* Note that a similar situation arises in 8.6 -- "It is a compile-time 
error if a return statement (§14.17) appears anywhere within an instance 
initializer." -- and 8.3.2 -- "It is a compile-time error if the keyword 
this (§15.8.3) or the keyword super (§15.11.2, §15.12) occurs in the 
[variable] initializer.". */

The JLS text is accurate, but not precise. Precisely characterizing the 
context where something appears is hard: formal grammar-driven 
descriptions of enclosing and enclosed contexts are tough to understand, 
while informal narrative descriptions inevitably bring their own 
incongruities. For example, under the narrative rule "... unless it 
appears within a local class declaration contained in that static 
initializer", the code below is legal only because in judging that the 
`return` "appears within a local class declaration", you somehow know to 
treat the immediately enclosing method declaration as if it was invisible:

class A {
   static {
     class B {  int m() { return 5; }  }
   }
}

But now someone else will say the rule should be: "... unless it appears
within a method declaration of a local class declaration contained in
that static initializer". Add in a sub-clause for "the body of a lambda 
expression" etc, and now the qualifying "unless" clause is longer than 
the main "compile-time error" clause.

I tend to think of the JLS' traditional phrasing in 8.3.2, 8.6, and 8.7 
as delivering 90% of the precision for a fraction of the cost (i.e. 
burden on the reader) that delivering 100% would require.

I concede that the word "anywhere" is a potential source of trouble. I 
believe it was aiming for the sense of "anywhere within the Block of the 
instance initializer -- you can't have a `return` statement directly 
enclosed by the Block OR enclosed by other statements within the Block". 
That's an important rule in itself. On balance, I don't see much benefit 
from tweaking the narration here.

Alex


More information about the jls-jvms-spec-comments mailing list