我有下一个代码:
for(int i = 0; i < fileRefernces.size(); i++) {
Thread t = new Thread(new Runnable() {
public void run() {
JLabel pageNumber = new JLabel("<html><font color='#003b86'>PAGE" + (i + 1) + "</font></html>", JLabel.LEFT);
JLabel imageLabel = new JLabel(image, JLabel.LEFT);
// content would be probably some Image class or byte[]
// or:
// InputStream in = Loc.openStream();
// read image from in
}
});
}
但是,就在此刻分配值时,我得到了下一个错误:
错误:从内部类引用的局部变量必须是final或 有效地最终
如何为这些变量赋值?
答案 0 :(得分:1)
错误:从内部类引用的局部变量必须是final或有效的final
此编译器错误正是您的问题,因为在Java中,正如编译错误所言,在lambda或内部类中使用的所有局部变量必须为 final或有效地为final 。
基本上,这意味着您无法使用在方法中定义的任何局部变量(内部类中的非),除非它们是最终的/实际上是最终的。拿这个:
root.after
变量
public void someMethod() {
int x = 5;
Thread thread = new Thread(new Runnable() {
public void run() {
x = 4; // This is a compilation error.
}
});
thread.start();
}
实际上不是最终变量,因为该值在run方法内部已更改,因此无法使用。
现在接受这个:
x
此也还会导致编译错误,因为即使public void someMethod() {
int x = 5;
x = 4;
Thread thread = new Thread(new Runnable() {
public void run() {
System.out.println(x); // This is a compilation error.
}
});
thread.start();
}
的值在运行方法之外 发生了更改,但由于该更改,它实际上不是最终的
以上两个示例均带有局部变量,这些局部变量实际上不是最终变量。现在,在这里:
x
此处public void someMethod() {
int x = 5;
final int y = 6;
List<String> list = new ArrayList<>();
Thread thread = new Thread(new Runnable() {
public void run() {
System.out.println(x);
System.out.println(y);
list.add("String added in thread");
list.forEach(System.out::println); // Will print "String added in thread"
}
});
thread.start();
}
,x
和y
都是有效的变量,可以在内部类中使用,因为它们都是有效的final 或< em>最终。
答案 1 :(得分:1)
使用局部最终变量,您只需实例化一次即可解决该问题。
final Image finalImage = image;
for(int i = 0; i < fileRefernces.size(); i++) {
final int finalCounter = i + 1;
Thread t = new Thread(new Runnable() {
public void run() {
JLabel pageNumber = new JLabel("<html><font color='#003b86'>PAGE" + finalCounter + "</font></html>", JLabel.LEFT);
JLabel imageLabel = new JLabel(finalImage, JLabel.LEFT);
// commented code
}
});
}