Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

If you do an asynchronous callback in an inner loop that tries to log the loop counter and a calculated value at the same time, you will find that the loop counter has incremented underneath you and you'll get for instance '20' for all of the logs. That was my introduction to this sort of problem.

The solution as I said elsewhere is to pop out the inner block to a separate function, where the value of the counter is captured when the outer function is called, not when the inner one runs.



I don't think you remember well how you triggered this error, since Java just doesn't allow you to reference a non-final variable from an inner function. It sounds like you're talking about code like this, but this just doesn't compile:

  for (int i = 0; i < n; i++) {
    callbacks.add(new Callback(){
      public void Call() {
        System.out.println(i); //compiler error: local variables referenced from an inner class must be final or effectively final
      }
    });
  }
  for (var f : callbacks) {
    f.Call();
  }
Note that code like this works, and does the expected thing:

  for (int i : new int[]{0, 1, 2}) {
    callbacks.add(new Callback(){
      public void Call() {
        System.out.println(i);
      }
    });
  }
  for (var f : callbacks) {
    f.Call();
  } //prints 0 1 2




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: