Java 为什么在这种情况下我必须使用final?

Java 为什么在这种情况下我必须使用final?,java,final,Java,Final,情况如下: 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 Fil

情况如下:

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.需要为final的变量是该方法的所有局部变量

2.局部变量都在匿名类中引用


实际上,RunnableActionListener都是接口。这有关系吗?我在上找到了答案,但我发现在答案下面的评论中有一个很长的讨论。我现在有点困惑,请你帮我澄清一下,并提前向你表示感谢。

局部变量只要在范围内就可以使用。如果该局部变量超出范围,它将被清除。如果在局部变量消失后调用匿名函数中的该函数,则当它尝试使用不再存在的变量时,将导致未定义的行为。这就是问题所在。通过使局部变量为final,编译器跟踪值而不是变量,并将值内联到匿名函数中,而不是指向值的指针