java:从内部类访问局部变量循环器;需要声明为final,但变量可能尚未初始化

java:从内部类访问局部变量循环器;需要声明为final,但变量可能尚未初始化,java,variables,interface,parameters,scope,Java,Variables,Interface,Parameters,Scope,我使用有点像的东西来创建一个类,它为我经常重用的方法实现了一个简单的接口,但方式不同 我可以用两种不同的方法让它工作,但我更喜欢这一种,这是乔恩·斯基特提供的 public class InterfaceProblemExample implements Runnable{ public static void main(String... args) { new InterfaceProblemExample().run(); } @Override

我使用有点像的东西来创建一个类,它为我经常重用的方法实现了一个简单的接口,但方式不同

我可以用两种不同的方法让它工作,但我更喜欢这一种,这是乔恩·斯基特提供的

public class InterfaceProblemExample implements Runnable{

    public static void main(String... args) {
        new InterfaceProblemExample().run();
    }

    @Override
    public void run() {
        int dim = 3;
        final double[][] oldMatrix = new double[dim][dim];
        final double[][] newMatrix = new double[dim][dim];

        final AtomicReference<Looper> wrapper = new AtomicReference<Looper>();
        Looper looper = new Looper(dim, new Commandable() {
            @Override
            public void execute() {
                int axis1 = wrapper.get().getiAxis1();
                int axis2 = wrapper.get().getiAxis2();
                newMatrix[axis1][axis2] = oldMatrix[axis1][axis2] + 2.5;
            }
        });
        wrapper.set(looper);
        looper.execute();
    }

    public interface Commandable {
        public abstract void execute();
    }

    public class Looper implements Commandable {

        private Commandable command;
        private int iAxis1;
        private int iAxis2;
        private int dim;

        public Looper(int dim, Commandable command) {
            this.command = command;
            this.dim = dim;
        }

        public void setCommand(Commandable command) {
            this.command = command;
        }

        @Override
        public void execute() {
            for (iAxis2 = 1; iAxis2 < dim; iAxis2++) {
                for (iAxis1 = 0; iAxis1 < iAxis2; iAxis1++) {
                    command.execute();
                }
            }
        }

        public int getiAxis1() {
            return iAxis1;
        }

        public int getiAxis2() {
            return iAxis2;
        }

        public int getDim() {
            return dim;
        }
    }
}
公共类接口问题示例实现可运行{
公共静态void main(字符串…参数){
新建InterfaceProblemExample().run();
}
@凌驾
公开募捐{
int-dim=3;
最终双精度[][]旧矩阵=新双精度[dim][dim];
最终双精度[][]新矩阵=新双精度[dim][dim];
最终AtomicReference包装器=新的AtomicReference();
活套活套=新活套(dim,新命令(){
@凌驾
public void execute(){
int axis1=wrapper.get().getiAxis1();
int axis2=wrapper.get().getiAxis2();
新矩阵[axis1][axis2]=旧矩阵[axis1][axis2]+2.5;
}
});
套(活套);
looper.execute();
}
可命令的公共接口{
公共抽象void execute();
}
公共类循环器实现可命令的{
私人命令;
私人互联网1;
私人互联网2;
私人智能交通系统;
公共活套(int dim,可命令命令){
this.command=命令;
this.dim=dim;
}
公共void setCommand(可命令命令){
this.command=命令;
}
@凌驾
public void execute(){
对于(iAxis2=1;iAxis2
您实际上得到了一个循环依赖:您的
活套
需要用
可命令的
初始化,而
可命令的
需要用
活套
初始化。编译器的抱怨是绝对正确的-想象一下,如果
Looper
构造函数调用
command.execute()
,那么在初始化
Looper
变量之前,它会尝试使用它(在匿名内部类中)

你需要打破这种循环。例如:

  • 您可以使
    活套
    具有
    可设置命令的
    方法
  • 您可以使您的
    可命令
    实现具有
    setLooper
    方法
  • 您可以将
    Looper
    传递到
    execute
    方法中
作为一种非常老套的方法,您可以使用数组或原子引用作为“包装器”:

public void run(){
最终AtomicReference包装器=新的AtomicReference();
活套活套=新活套(新命令(){
@凌驾
public void execute(){
System.out.println(“这很简单:”);
System.out.println(“这不容易:+wrapper.get().getI());
}
});
套(活套);
looper.execute();
}

但这很糟糕。

你应该包括这是什么语言/平台,很多人可能会因为模棱两可而跳过回答,因为现在有很多语言看起来很相似。@Osirisgottra啊,谢谢。你的前两个答案很有道理,并立即解决了我的问题。我不知道第三个问题将如何实现,但最后一个问题令人惊讶。谢谢你,乔恩。这正是我想要的答案。我会有很多乐趣去理解this@doctordoder:第三种方法需要更改
Commandable
。例如,它需要处理的对象类型可以是泛型的。如果你想要与上一个相同的数组,请告诉我。如果你给我5分钟的时间,我会告诉你我到底需要什么。好吧,我出于某种原因被锁定在GitHub之外,但我编辑了原始问题,以包含我实际要做的事情的版本。
public void run() {
    final AtomicReference<Looper> wrapper = new AtomicReference<Looper>();
    Looper looper = new Looper(new Commandable() {
        @Override
        public void execute() {
            System.out.println("This is easy: ");
            System.out.println("This isn't easy: " + wrapper.get().getI());
        }
    });
    wrapper.set(looper);
    looper.execute();
}