情况如下:
import java.io.File;
public class FinalTest1 {
public static void main(String[] args) {
FinalTest1 finalTest1 = new FinalTest1();
finalTest1.test();
}
public void test(){
File fileToBeModifiedFile = new File("AFile");
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
modifyFile(fileToBeModifiedFile);
}
});
thread.start();
}
public void modifyFile(File file){
System.out.println("I'm going to modify the file");
}
}
同样适用于这种情况:
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
public class FinalTest2{
public void createUI(){
JFrame frame = new JFrame("Final Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(false);
JPanel mainPanel = new JPanel();
JButton button = new JButton("Button");
String string = "I am a string";
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
JOptionPane.showMessageDialog(null, string);
}
});
mainPanel.add(button,BorderLayout.CENTER);
frame.add(mainPanel,BorderLayout.CENTER);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
FinalTest2 finalTest = new FinalTest2();
finalTest.createUI();
}
}
我发现了这些情况的一些共同点。
1.需要最终的变量是该方法的所有局部变量。
2.局部变量都是在匿名类中引用的。
实际上 Runnable 和 ActionListener 都是接口。有关系吗?我在https://stackoverflow.com/a/1299889/3378204找到了答案,但我发现在答案下面的评论中有一个很长的讨论。我现在有点困惑,请你帮我澄清一下,并提前谢谢你。
答案 0 :(得分:2)
局部变量只要保留在范围内就会持续。如果该局部变量超出范围,则会清除它。如果在局部变量消失后调用匿名中的该函数,则在尝试使用不再存在的变量时将导致未定义的行为。那就是问题出现的地方。通过使局部变量为final,编译器会跟踪值而不是变量,并将值内联到匿名函数中,而不是指向值的指针。