可运行的计数器 'local variables referenced from an inner class must be final or effectively final'

counter in runnable 'local variables referenced from an inner class must be final or effectively final'

我的 runnable 中需要一个计数器,我试着写了一些看起来像

的东西
public class Foo {
  private class Bar {
    public void barMethod() {
      int counter = 0;
      Bar instance = this;
      BukkitTask barTask = new BukkitRunnable() {
        @Override
        public void run() {
          if (counter == 5) {
            this.cancel();
            return;
          }
          instance.doStuff(); // don't worry it exists
          counter++;
        }
      }.runTaskTimer(this.plugin, 0L, 2L);
    }
  }
}

但是,尝试编译它会导致错误

local variables referenced from an inner class must be final or effectively final

所以我发现问题是我尝试从 runnable 中更新 counter 变量。

然而,这让我对如何在 runnable 上有一个计数器一无所知。

如何确保 runnable 最多只运行 5 次?

标准的解决方法是用 single-element 数组替换:

public class Foo {
  private class Bar {
    public void barMethod() {
      int[] counter = new int[] { 0 };
      Bar instance = this;
      BukkitTask barTask = new BukkitRunnable() {
        @Override
        public void run() {
          if (counter[0] == 5) {
            this.cancel();
            return;
          }
          instance.doStuff(); // don't worry it exists
          counter[0]++;
        }
      }.runTaskTimer(this.plugin, 0L, 2L);
    }
  }
}

变量本身永远不会被重新分配,所以它实际上是最终的。

您可以通过以下方式修复此错误:

public class Foo {
    private class Bar {
        public void barMethod() {
            Bar instance = this;
            BukkitTask barTask = new BukkitRunnable() {
                int counter = 0;

                @Override
                public void run() {
                    if (counter == 5) {
                        this.cancel();
                        return;
                    }
                    instance.doStuff(); // don't worry it exists
                    counter++;
                }
            }.runTaskTimer(this.plugin, 0L, 2L);
        }
    }
}

此致