Making the variable final
is necessary because under the hood, anonymous inner classes like that are simply syntactic sugar that compile to a nested class outside the scope of the containing method.
This means that none of the variables declared inside of the method are accessible to the inner class, so the compiler pulls another trick - and copies the value in a hidden constructor for your class. To avoid programmer confusion where this copy is not updated to match changes to the variable in the method, it must be final to make sure there are no such changes.
Since your goal here is to have an incrementing integer, and only the reference must be final (the object itself need not be immutable) you could declare a final AtomicInteger i
and then increment it as you wish from the callback.