java—如何在代码的其他部分中使用在封闭范围中定义的变量?我的代码粘贴在下面

cpjpxq1n  于 2021-06-27  发布在  Java
关注(0)|答案(2)|浏览(270)
JSpinner spinner = new JSpinner(model1);
spinner.setBounds(101, 180, 61, 25);
spinner.addChangeListener(new ChangeListener() {
    public void stateChanged(ChangeEvent e) {
        JSpinner s = (JSpinner)e.getSource();
        int val = (int) s.getValue();
    }
});
frame.getContentPane().add(spinner);

我想用这个变量 val 在我的代码的其他部分,超出了它的范围。我该怎么做?

r1zk6ea1

r1zk6ea11#

内部类中使用的局部变量必须声明为final,但是可以使用某种类型的变量保持器,如数组、原子类或自定义保持器。
例子:

int[] holder1 = new int[1];
AtomicReference<Integer> holder2 = new AtomicReference<>();
MyHolder<Integer> holder3 = new MyHolder<>();
var holder4 = new Object() { int value; }; // Java 10

JSpinner spinner = new JSpinner(model1);
spinner.setBounds(101, 180, 61, 25);
spinner.addChangeListener(new ChangeListener() {
    public void stateChanged(ChangeEvent e) {
        JSpinner s = (JSpinner)e.getSource();
        int val = (int) s.getValue();

        holder1[0] = val;
        holder2.set(val);
        holder3.setValue(val);
        holder4.value = val;
    }
});
frame.getContentPane().add(spinner);
ocebsuys

ocebsuys2#

@皮奥特żmudzin的解决方案是可行的,因为在闭包中捕获的变量实际上是最终的。但是,值得注意的是,您基本上是在传递一个函数,或者更具体地说是传递一个包含函数的匿名对象。如果您不知道传递给它的代码何时调用此传递的函数,请依赖 holder.value 可能有危险,这取决于你在哪里使用它。您可以向自定义持有者添加一个附加成员,如下所示:

class MyHolder<T> 
{
    T value;
    boolean hasValue = false;
}

现在您可以检查变量是否设置为:

var holder1 = new MyHolder<Integer>(); 
var holder2 = new Object() { int value; boolean hasValue = false}; // Java 10

JSpinner spinner = new JSpinner(model1);
spinner.setBounds(101, 180, 61, 25);
spinner.addChangeListener(new ChangeListener() {
    public void stateChanged(ChangeEvent e) {
        JSpinner s = (JSpinner)e.getSource();
        int val = (int) s.getValue();

        holder1.hasValue = true;
        holder1.value = val;
        holder2.hasValue = true;
        holder2.value = val;
    }
});
frame.getContentPane().add(spinner);

if (holder.hasValue) { 
   // use holder.Value 
}

当然,如果您确切地知道函数的调用时间,这不是问题。

相关问题