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


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,这超出了它的范围。我该怎么做?

内部类中使用的局部变量必须声明为final,但是您可以使用某种变量持有者,如数组、Atomic类或自定义持有者。

示例:

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

@PiotrŻ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 
}

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

最新更新