Java:在封闭范围内定义的局部variablesmi必须是最终的或有效的最终的
我得到的错误,如主题,我恳请问你如何修复它…错误是在menuItem循环,我尝试设置textArea前景颜色从menuItemselect一个:(颜色[米])
String[] colors = { "blue", "yellow", "orange", "red", "white", "black", "green", }; JMenu mnForeground = new JMenu("Foreground"); for (int mi=0; mi<colors.length; mi++){ String pos = Character.toUpperCase(colors[mi].charAt(0)) + colors[mi].substring(1); JMenuItem Jmi =new JMenuItem(pos); Jmi.setIcon(new IconA(colors[mi])); Jmi.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { JMenuItem item = (JMenuItem) e.getSource(); IconA icon = (IconA) item.getIcon(); Color kolorIkony = getColour(colors[mi]); // ERROR HERE: (colors[mi]) textArea.setForeground(kolorIkony); } }); mnForeground.add(Jmi); } public Color getColour(String colour){ try { kolor = Color.decode(colour); } catch (Exception e) { kolor = null; } try { final Field f = Color.class.getField(colour); kolor = (Color) f.get(null); } catch (Exception ce) { kolor = Color.black; } return kolor; }
这个错误意味着你不能在内部类中使用局部variablesmi
。
要在内部类中使用variables,必须声明它是final
。 只要mi
是循环的计数器,并且不能分配final
variables,则必须创build一个解决方法来获取可以在内部类中访问的final
variables中的mi
值:
final Integer innerMi = new Integer(mi);
所以你的代码将是这样的:
for (int mi=0; mi<colors.length; mi++){ String pos = Character.toUpperCase(colors[mi].charAt(0)) + colors[mi].substring(1); JMenuItem Jmi =new JMenuItem(pos); Jmi.setIcon(new IconA(colors[mi])); // workaround: final Integer innerMi = new Integer(mi); Jmi.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { JMenuItem item = (JMenuItem) e.getSource(); IconA icon = (IconA) item.getIcon(); // HERE YOU USE THE FINAL innerMi variable and no errors!!! Color kolorIkony = getColour(colors[innerMi]); textArea.setForeground(kolorIkony); } }); mnForeground.add(Jmi); } }
你在这里有一个非局部variables ( https://en.wikipedia.org/wiki/Non-local_variable ),即你访问一个匿名类的方法的局部variables。
方法的局部variables保存在堆栈中,并在方法结束后立即丢失,但是即使在方法结束之后,本地内部类对象仍然在堆中,并且需要访问这个variables(这里,当一个动作被执行)。
我会build议两个解决方法:要么你让你自己的类,实现actionlistenner
,并作为构造函数参数,你的variables,并保持它作为一个类的属性。 因此你只能在同一个对象中访问这个variables。
或者(这也许是最好的解决scheme)只是限定variablesfinal
的副本,以便在内部作用域中访问它,因为错误使其成为一个常量:
这将适合你的情况,因为你没有修改variables的值。
是的,这是因为你正在访问匿名内部类中的mi
variables,深层内部发生的是variables的另一个副本被创build并将在匿名内部类中使用,所以为了保证数据的一致性,编译器会尝试限制你从改变mi
的价值,这就是为什么它告诉你把它设置为最终。