代码之家  ›  专栏  ›  技术社区  ›  minseong

runnable“从内部类引用的局部变量必须是final或有效final”中的计数器

  •  0
  • minseong  · 技术社区  · 6 年前

    我的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
    

    所以我发现问题是我试图更新 counter 来自runnable内部的变量。

    然而,这让我不知道如何在runnable上设置计数器。

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

    2 回复  |  直到 6 年前
        1
  •  1
  •   Alexey Romanov    6 年前

    标准的解决方法是替换为单元素阵列:

    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);
        }
      }
    }
    

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

        2
  •  1
  •   AlphaConqueror    6 年前

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

    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);
            }
        }
    }
    

    真诚地