【发布时间】:2017-12-08 04:00:53
【问题描述】:
我需要创建几个按钮并上传文件。所以我想创建一个函数来设置这些按钮。但是,我的 setNewButton 内部出现编译错误。
我的代码如下所示:
public class Solution extends JFrame {
private static final String FILE_NAME_1 = "my file1";
private File file1;
private void setNewButton(Container contentPane, final String fileName, String format, File file) {
contentPane.add(Box.createVerticalStrut(5));
final Label label = new Label("Select " + fileName + " in ." + format +" format");
contentPane.add(label);
contentPane.add(Box.createVerticalStrut(10));
Button selection = new Button("Select " + fileName);
contentPane.add(selection);
selection.addActionListener(new FileSelectionListener("Only " + format + " is allowed", format) {
@Override
protected void setSelection(File selectedFile) {
file = selectedFile; // compilation error here
label.setText("Selected" + fileName + selectedFile.getAbsolutePath());
}
});
}
public uploadFiles() {
Container contentPane = this.getContentPane();
setNewButton(contentPane, FILE_NAME_1, "xls", file1);
}
}
错误是:Variable file is accessed from within inner class, needs to be declared final
我在stackoverflow中检查了一些类似的问题。我知道file 必须像label 和fileName 一样是最终的。
但是这里的file 可能是final,因为我想将selectedFile 分配给它。
我想知道这个问题是否有任何解决方法。
任何帮助将不胜感激。 :)
感谢@M。普罗霍罗夫和@Chang Liu。 根据 JLS 8.1.3. Inner Classes and Enclosing Instances
任何使用但未在内部类中声明的局部变量、形参或异常参数必须声明为 final 或实际上是 final,否则在尝试使用时会发生编译时错误。
所以当我尝试在FileSlectionListener 内部发送参数file 时,会出现编译错误。但是,Solution 中的成员file1 不是局部变量,所以如果我从我的方法中删除file,就不会出错。所以@talex 的答案在这种情况下是正确的。
但是,由于我的问题是找到一种将File 传递给内部类并使用selectedFile 分配变量的方法,因此我找不到解决方法。我的解决方法是基于@Chang Liu 的回答。
我修改后的代码如下:
public class Solution extends JFrame {
private static final String FILE_NAME_1 = "my file1";
private File file1;
private void setNewButton(Container contentPane, final String fileName, String format) {
contentPane.add(Box.createVerticalStrut(5));
final Label label = new Label("Select " + fileName + " in ." + format +" format");
contentPane.add(label);
contentPane.add(Box.createVerticalStrut(10));
Button selection = new Button("Select " + fileName);
contentPane.add(selection);
selection.addActionListener(new FileSelectionListener("Only " + format + " is allowed", format) {
@Override
protected void setSelection(File selectedFile) {
setFile(selectedFile, fileName); // no compilation error here
label.setText("Selected" + fileName + selectedFile.getAbsolutePath());
}
});
}
public uploadFiles() {
Container contentPane = this.getContentPane();
setNewButton(contentPane, FILE_NAME_1, "xls", file1);
}
private void setFile(File file, String fileName) {
switch (fileName) {
case FILE_NAME_1:
sollFile = file;
break;
default:
throw new AssertionError("Unknown File");
}
}
}
不过,如果您有更好的答案,欢迎给我任何建议。 :)
【问题讨论】:
-
我正在寻找
selectedFile的声明位置。那是哪里? -
@markspace 是 setSelection 方法的参数。
-
请参阅 this JLS 了解您的错误。它基本上归结为 - java 强烈禁止(通过编译错误)匿名内部类(包括 lambdas)“捕获”可能在内部类实例处于活动状态时重新分配的变量。
-
谢谢@M.Prokhorov 它有帮助。
标签: java inner-classes final