java中内部类变量的访问
-
29-09-2019 - |
题
我正在尝试创建一个 JLabels 数组,单击时所有这些标签都应该消失。当尝试通过内部类设置鼠标侦听器时,问题就出现了,该内部类需要访问用于声明标签的循环的迭代变量。代码是不言自明的:
for(int i=1; i<label.length; i++) {
label[i] = new JLabel("label " + i);
label[i].addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent me) {
label[i].setVisible(false); // compilation error here
}
});
cpane.add(label[i]);
}
我认为我可以通过使用来克服这个问题 this
或者可能 super
而不是调用 label[i]
在内部方法中,但我一直无法弄清楚。
编译错误是:局部变量 i 从内部类内部访问;需要宣布最终`
我确信答案一定是我没有想到的非常愚蠢的事情,或者也许我犯了一些小错误。
任何帮助,将不胜感激
解决方案
你的局部变量必须是 final
从内部(和匿名)类访问。
您可以将代码更改为如下所示:
for (int i = 1; i < label.length; i++) {
final JLabel currentLabel =new JLabel("label " + i);
currentLabel.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent me) {
currentLabel.setVisible(false); // No more compilation error here
}
});
label[i] = currentLabel;
}
来自 JLS :
任何在内部类中使用但未声明的局部变量、形式参数或异常参数都必须声明
final
.任何在内部类中使用但未声明的局部变量都必须明确赋值 (§16) 在内部类的主体之前。
资源 :
其他提示
如果您在访问时遇到问题 i
, ,在内部类的范围之外创建另一个变量(例如前 label[i].addMouseListener(...)
):
for(int i=1; i<label.length; i++) {
label[i] = new JLabel("label " + i);
final int localI = i;
label[i].addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent me) {
label[localI].setVisible(false);
}
});
cpane.add(label[i]);
}
你也可以使用 getSource
在你的程序中。之后,您可以在以下命令的帮助下访问您的组件 typecasting
. 。它将减少额外的代码行,您的代码看起来像这样
for (int i = 1; i < label.length; i++) {
currentLabel.addMouseListener(new MouseAdapter(e) {
public void mouseClicked(MouseEvent me) {
JLabel label = (JLabel) me.getSource();
}
});
}
发生这种情况是因为 label
未指定为 final
.
将标签数组声明为:
final JLabel[] label;
代替:
JLabel[] label;
你的 MouseAdapter
不是内部类;这是一个 匿名的 班级。匿名类只能引用 final
其封闭代码的变量。
匿名内部类只能访问封闭方法的变量 final
.
不隶属于 StackOverflow