我想创建一些JFormattedTextFields
,但始终得到ArrayIndexOutOfBoundsException
,我不明白为什么。
变量globalZaehler2
是51然后我将得到异常。但我的循环说它必须< field.length
(即51)。那么globalZaehler2
不能是51?当我使用((JFormattedTextField)field[globalZaehler2]).selectAll();
for (globalZaehler2 = 0; globalZaehler2 < field.length; globalZaehler2++) {
if (field[globalZaehler2] instanceof JFormattedTextField) {
((JFormattedTextField)field[globalZaehler2]).addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
((JFormattedTextField)field[globalZaehler2]).selectAll();
// do something with the text in the field
}
});
}
}
答案 0 :(得分:3)
我们无法轻易说出来,但名称globalZaehler2
让它听起来像是一个字段,而不是一个局部变量。使用字段作为&#34;索引&#34; for
循环中的变量几乎总是一个坏主意...我不记得上一次我希望对象的状态在循环中如此改变。
这意味着在执行actionPerformed
时,您可以使用不同长度的字段以其他方式执行循环。但是,如果你试图使它成为一个局部变量,你会遇到一个不同的问题,因为你在匿名内部类中引用它 - 这意味着它需要是一个最终的局部变量......这就是真正的问题。
基本上,您希望actionPerformed
中的代码使用globalZaehler2
的值来进行循环的迭代 ...但它没有在执行期间执行循环的迭代......它在动作侦听器触发时执行。
你可以通过在循环中声明一个局部变量来解决这个问题:
for (globalZaehler2 = 0; globalZaehler2 < field.length; globalZaehler2++) {
// In Java 8 you wouldn't need the final part
final int copy = globalZaehler2;
// Use copy instead of globalZaehler2 within actionPerformed
}
但是,更好的解决方案有两个方面:
for
循环中的变量作为数组的索引,并且您正在遍历整个数组,请使用增强型环在您的情况下,这将是:
// We don't know the type of field, so it's hard to guess the
// type here. Likewise I *would* use the name field, but that's the
// name of the array... it should probably be called fields, as it's
// naturally plural...
for (Object fooField : field) {
if (fooField instanceof JFormattedTextField) {
// Again, don't bother with final in Java 8
final JFormattedTextField textField = (JFormattedTextField) fooField;
textField.addActionListener(new ActionListener()) {
@Override public void actionPerformed(ActionEvent e) {
textField.selectAll();
// etc
}
});
}
}
现在你自然地在循环中获得了一个新的局部变量(textField
),所以它可以有效地final
,并在actionPerformed
方法中使用。