我收到错误“从内部类中访问局部变量框;需要声明为final”。这似乎没问题,但我不认为这是最好的解决方案,所以我希望别人可以帮助我。这是我的代码:
public void showPublisherBox(JComboBox box) {
if (publisherBox == null) {
publisherBox = new AddPublisherForm();
publisherBox.setLocationRelativeTo(this);
}
publisherBox.addWindowListener(new WindowAdapter()
{
public void windowClosing(WindowEvent we)
{
this.populatePublishers(box);
}
private void populatePublishers(JComboBox box){
box.setModel(db.getPublishers());
}
});
publisherBox.setVisible(true);
}
Publisher表单只是一个新的JFrame,它打开并接收一些信息,当它关闭时,我希望通过从我的db.getPublishers()方法设置模型来重新填充JComboBox。
那么有更好的方法来做我在这里做的事情,还是我必须宣布一些事情作为最终的?
由于
答案 0 :(得分:8)
由于您未在外部代码中修改box
,因此使用final
正是解决此问题的正确方式。这是对自己(以及编译器)的承诺,box
的值不会在封闭范围内发生变化。编译器会告诉你是否违反了这个承诺。
使用final
没有编译时或运行时成本。
答案 1 :(得分:4)
当匿名内部类(例如您的WindowAdapter
)引用封闭范围中的变量(如“box”)时,Java要求将它们声明为final
。
避免将box
声明为final
的一种方法是让WindowAdapter
成为一个命名类,它接受box
作为构造函数参数:
public void showPublisherBox(JComboBox box) {
if (publisherBox == null) {
publisherBox = new AddPublisherForm();
publisherBox.setLocationRelativeTo(this);
}
publisherBox.addWindowListener(new MyWindowClosingHandler(box, db));
publisherBox.setVisible(true);
}
// ...
class MyWindowClosingHandler extends WindowAdapter {
private JComboBox box;
MyWindowClosingHandler(JComboBox box, DB db) {
this.box = box;
this.db = db;
}
public void windowClosing(WindowEvent we) {
populatePublishers();
}
private void populatePublishers(){
box.setModel(db.getPublishers());
}
});
}
答案 2 :(得分:1)
不。在这种情况下,声明为final。无论如何,参考文献都没有改变。
答案 3 :(得分:1)
本地类使用的局部变量必须声明为final。在这种情况下,变量是一个方法参数,无论如何都不会分配给它,所以我认为没有理由不将它声明为final。
毋庸置疑,此声明对方法的调用者没有任何影响。它只声明该方法的主体不会修改引用的本地副本。
答案 4 :(得分:0)
每次声明一个变量时都应该键入“Final” - 我不知道为什么Java没有将final作为默认值并且需要一个“Variable”关键字。我只是说大多数变量应该是最终的,除非另有证明。
也就是说,你总是可以创建一个完整的类而不是一个匿名的内部类,并将变量传递给构造函数 - 这将是“正确”的方法。无论如何,匿名内部类是一个坏习惯 - 他们不鼓励代码重用(内部类不能在另一个地方重用为监听器,而如果它是一个完整的类,它很容易重用 - 我在重构时使用了这种技术消除大量冗余代码。