Error: local variable imagesLabel is accessed from within inner class; needs to be declared final (Java)
Error: local variable imagesLabel is accessed from within inner class; needs to be declared final (Java)
背景
在下面的屏幕截图中,用户应该能够通过单击其中一个单选按钮来更改图像:
单击单选按钮时,图片应更改为另一张。
我已将所有图像放入一个数组中。
问题
到目前为止,当我尝试编译代码时(请参阅下面的源代码),编译器给出以下错误:
Error: local variable imagesLabel
is accessed from within inner class; needs to be declared final
一旦我在相应变量前添加 final
,编译时出现以下错误:
Error: <identifier> expected
Java代码(添加final
后)
Icon[] images = new Icon[3];
// Get the images and store them in the images array. These images
// were manually resized to be similar in size prior to writing the
// program.
images[0] = new ImageIcon("/Users/grimygod/Desktop/negativeFilterExample.png");
images[1] = new ImageIcon("/Users/grimygod/Desktop/reflect.png");
images[2] = new ImageIcon("/Users/grimygod/Desktop/colorSubtraction.png");
// The images will be displayed as the image on a JLabel without text
JLabel imagesLabel = new JLabel();
// Set the initial image to be the negative filter, and add it to the panel,
// since the radio button for the negative filter is initially selected.
imagesLabel.setIcon(images[0]);
iconPanel.add(imagesLabel);
radioButtonPanel.add(iconPanel);
// Creation of "Select An Image & Apply Filter!" button
JButton selectButton = new JButton("Select An Image & Apply Filter!");
submitButtonPanel.add(selectButton);
radioButtonPanel.add(submitButtonPanel);
// Makes the whole window visible
testFrame.setVisible(true);
// First button is selected when program is ran
button1.setSelected(true);
button1.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
final imagesLabel.setIcon(images[2]); // <<<<< ERROR in this line
}
});
您可以执行以下任一操作来解决问题:
一个。将 imagesLabel
声明为 final
final JLabel imagesLabel = new JLabel();
乙。将 imagesLabel
声明为实例变量,即在方法外部。换句话说,在 class 本身声明它。
确保从 final imagesLabel.setIcon(images[2]);
中删除 final
即它应该只是 imagesLabel.setIcon(images[2]);
问题 A
您在添加侦听器时定义了 ActionListener
类型的 anonymous inner class,请参见下面代码中的 (1)。然后你尝试访问 声明在外部(内部class)的变量imagesLabel
,见下面代码中的(2)。由于此变量声明为非最终,您不能在匿名内部class[=75]中使用它 =] 像这样。
► 因此编译失败并显示消息:
Error: local variable imagesLabel is accessed from within inner class; needs to be declared final
状态 A 中的代码(添加 final
之前):
button1.addActionListener(new ActionListener() { // (1)
@Override
public void actionPerformed(ActionEvent e) {
imagesLabel.setIcon(images[1]); // (2) <<<<< ERROR in this line
}
});
问题 B
尝试解决它,您按照消息的说明进行操作,并希望直接在此行中 "declare" 变量 imagesLabel
作为 final
- 在下面的代码中标记为 (3) .
但是第(3)行不是变量imagesLabel
的声明的位置,而不是方法调用在这个实例变量上。
编译器读取以 final
开头的源代码行,并期望此后有一个 标识符 ,但是有一个 方法调用 .
► 因此编译失败并显示消息:
Error: <identifier> expected
状态B中的代码(添加final
后):
button1.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
final imagesLabel.setIcon(images[1]); // (3) <<<<< ERROR in this line
}
});
⚠ 注意: 相同的编译错误和修复(如 )适用于在同一行中用作参数的变量 images
(3 ) 以上。
解决方案
您必须在声明变量 imagesLabel
(以及 images
数组)的地方使用修饰符 final
。然后你可以在内部 class 中访问它,就像首先在代码状态 A:
final Icon[] images = new Icon[3]; // <<< here is the other declaration
/* ... lines of code left out for clarity ... */
// The images will be displayed as the image on a JLabel without text
final JLabel imagesLabel = new JLabel(); // <<< here is the declaration
/* ... lines of code left out for clarity ... */
button1.addActionListener(new ActionListener() { // (1) inner class
@Override
public void actionPerformed(ActionEvent e) {
imagesLabel.setIcon(images[1]); // (2) <<<<< now you can use the final declared variable imagesLabel
}
});
另见
- 问:Java: Anonymous inner class using a local variable
- 问:Why a non-final “local” variable cannot be used inside an inner class, and instead a non-final field of the enclosing class can?
- 问:Why are only final variables accessible in anonymous class?
- Tutorial on Inner Classes
背景
在下面的屏幕截图中,用户应该能够通过单击其中一个单选按钮来更改图像:
单击单选按钮时,图片应更改为另一张。 我已将所有图像放入一个数组中。
问题
到目前为止,当我尝试编译代码时(请参阅下面的源代码),编译器给出以下错误:
Error: local variable
imagesLabel
is accessed from within inner class; needs to be declared final
一旦我在相应变量前添加 final
,编译时出现以下错误:
Error: <identifier> expected
Java代码(添加final
后)
Icon[] images = new Icon[3];
// Get the images and store them in the images array. These images
// were manually resized to be similar in size prior to writing the
// program.
images[0] = new ImageIcon("/Users/grimygod/Desktop/negativeFilterExample.png");
images[1] = new ImageIcon("/Users/grimygod/Desktop/reflect.png");
images[2] = new ImageIcon("/Users/grimygod/Desktop/colorSubtraction.png");
// The images will be displayed as the image on a JLabel without text
JLabel imagesLabel = new JLabel();
// Set the initial image to be the negative filter, and add it to the panel,
// since the radio button for the negative filter is initially selected.
imagesLabel.setIcon(images[0]);
iconPanel.add(imagesLabel);
radioButtonPanel.add(iconPanel);
// Creation of "Select An Image & Apply Filter!" button
JButton selectButton = new JButton("Select An Image & Apply Filter!");
submitButtonPanel.add(selectButton);
radioButtonPanel.add(submitButtonPanel);
// Makes the whole window visible
testFrame.setVisible(true);
// First button is selected when program is ran
button1.setSelected(true);
button1.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
final imagesLabel.setIcon(images[2]); // <<<<< ERROR in this line
}
});
您可以执行以下任一操作来解决问题:
一个。将 imagesLabel
声明为 final
final JLabel imagesLabel = new JLabel();
乙。将 imagesLabel
声明为实例变量,即在方法外部。换句话说,在 class 本身声明它。
确保从 final imagesLabel.setIcon(images[2]);
中删除 final
即它应该只是 imagesLabel.setIcon(images[2]);
问题 A
您在添加侦听器时定义了 ActionListener
类型的 anonymous inner class,请参见下面代码中的 (1)。然后你尝试访问 声明在外部(内部class)的变量imagesLabel
,见下面代码中的(2)。由于此变量声明为非最终,您不能在匿名内部class[=75]中使用它 =] 像这样。
► 因此编译失败并显示消息:
Error: local variable imagesLabel is accessed from within inner class; needs to be declared final
状态 A 中的代码(添加 final
之前):
button1.addActionListener(new ActionListener() { // (1)
@Override
public void actionPerformed(ActionEvent e) {
imagesLabel.setIcon(images[1]); // (2) <<<<< ERROR in this line
}
});
问题 B
尝试解决它,您按照消息的说明进行操作,并希望直接在此行中 "declare" 变量 imagesLabel
作为 final
- 在下面的代码中标记为 (3) .
但是第(3)行不是变量imagesLabel
的声明的位置,而不是方法调用在这个实例变量上。
编译器读取以 final
开头的源代码行,并期望此后有一个 标识符 ,但是有一个 方法调用 .
► 因此编译失败并显示消息:
Error: <identifier> expected
状态B中的代码(添加final
后):
button1.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
final imagesLabel.setIcon(images[1]); // (3) <<<<< ERROR in this line
}
});
⚠ 注意: 相同的编译错误和修复(如 images
(3 ) 以上。
解决方案
您必须在声明变量 imagesLabel
(以及 images
数组)的地方使用修饰符 final
。然后你可以在内部 class 中访问它,就像首先在代码状态 A:
final Icon[] images = new Icon[3]; // <<< here is the other declaration
/* ... lines of code left out for clarity ... */
// The images will be displayed as the image on a JLabel without text
final JLabel imagesLabel = new JLabel(); // <<< here is the declaration
/* ... lines of code left out for clarity ... */
button1.addActionListener(new ActionListener() { // (1) inner class
@Override
public void actionPerformed(ActionEvent e) {
imagesLabel.setIcon(images[1]); // (2) <<<<< now you can use the final declared variable imagesLabel
}
});
另见
- 问:Java: Anonymous inner class using a local variable
- 问:Why a non-final “local” variable cannot be used inside an inner class, and instead a non-final field of the enclosing class can?
- 问:Why are only final variables accessible in anonymous class?
- Tutorial on Inner Classes