I have this code:
List<Runnable> r = new ArrayList<>();
for(int i = 0; i < 10; i++) {
r.add(new Runnable() {
@Override
public void run() {
System.out.println(i);
}
});
}
It obviously does not compile because i would need to be final to be used in the anonymous class. But I can’t make it final because it is not. What would you do? A solution is to duplicate it but I thought there might be a better way:
List<Runnable> r = new ArrayList<>();
for(int i = 0; i < 10; i++) {
final int i_final = i;
r.add(new Runnable() {
@Override
public void run() {
System.out.println(i_final);
}
});
}
EDIT just to make it clear, I used a Runnable here for the sake of the example, the question is really about anonymous classes, which could be anything else.
I think your solution is the simplest way.
Another option would be to refactor the creation of the inner class into a factory function that does it for you, then your loop itself could be something clean like:
And the factory function could just declare a final parameter:
I prefer this refactored approach because it keeps the code cleaner, is relatively self descriptive and also hides away all the inner class plumbing.
Random digression: if you consider anonymous inner classes to be equivalent to closures, then
generateRunnablePrinteris effectively a higher order function. Who said you can’t do functional programming in Java 🙂