0

The situation is like below:

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");
    }
}

And also for this situation:

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();
    }
}

I've found some common point of these situations.

1.The variable that need to be final is all local variable of that method.

2.The local variable is both referenced in a anonymous class.

Actually the Runnable and ActionListener are both interfaces. Does it matter? I've found an answer at https://stackoverflow.com/a/1299889/3378204 , but I've found there is a long discussion of it on the comments below the answer. I'm little confused now and could you please clarify it for me and thank you in advance.

Community
  • 1
  • 1
Eugene
  • 10,627
  • 5
  • 49
  • 67

1 Answers1

2

Local variables last as long as they remain in scope. If that local variable goes out of scope it gets cleaned up. If that function in the anonymous is called after the local variable is gone, it will lead to undefined behavior when it tries to use the variable that no longer exists. That's where the problem arises. By making the local variable final, the compiler keeps track of the value rather than the variable and will inline the value into the anonymous function rather than a pointer to the value.

Simba
  • 1,641
  • 1
  • 11
  • 16