Effectively final effective?

Peter Levart peter.levart at gmail.com
Sun Feb 28 02:29:41 PST 2010


The effectively final case of basic for-loop index variables is interesting in itself.

Usually we think of a particular basic for-loop construct:

  for ( LocalVariableDeclaration ; Expression ; ForUpdate ) Statement

as a shorthand for:

  {
    LocalVariableDeclaration ;
    while ( Expression ) {
      Statement
      ForUpdate ;
    }
  }

So if Expression or Statement or ForUpdate writes into local index variable then it is clearly 
not effectively final. Regardless of whether capturing non-final variables is allowed or not, 
capturing non-final for-loop index variables (by reference of course) is rarely a semantics that 
is desired so it should be marked with a warning. In that case you would have to rewrite you 
example either as:

for(int i = 0; i < 3; i++) {
  final int ii = i;
  funs.add(()->ii);
}

or:

for(int i = 0; i < 3; i++) {
  @SuppressWarnings("for loop index capture")
  funs.add(()->i);
}

Depending whether you want your program to print 012 or 333 (respectively).

That's what I think is a good enough solution to this problem.


Regards, Peter

On Sunday 28 February 2010 12:36:35 am John Nilsson wrote:
> Am I correct in interpreting the 4 sentiments listed below like so:
> 
> Given this code
> 
> List<()->int> funs = new ArrayList<>();
> for(int i = 0; i < 3; i++)
>   funs.add(()->i)
> for(()->i f : funs)
>   System.out.print(f.());
> 
> The following is the result
> 
> 1. Prints: 333
> 2. Compiler error at i++ (mutating a final variable)
> 3. Prints: 123
> 4. Compiler error at ()->i (trying to access a non-final var)
> 
> BR,
> John


More information about the lambda-dev mailing list