3

In a school test I used non final variables inside an anonyme inner class. On the the school Computer and on my private Computer(using x86 jre1.8.0_45) it is working.

However, on the teachers Laptop Eclipse is showing errors (The variables should use final). He is using jre1.8.0.x version (don't know the exact version).

Any ideas why it is working on my computer and not on his computer?

In this code example the no final object jLabel is used inside the actionPerformed function of the ActionListener:

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JLabel;

public class Main {
    public Main(String[] args) {
        JLabel jLabel = new JLabel();
        JButton button = new JButton();
        button.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent arg0) {
                jLabel.setText("xyz");

            }
        });
    }
}
4
  • 2
    Sounds strange, should be either a field variable or declared final as far as I can tell Commented Dec 7, 2015 at 14:52
  • Is it a warning or error ? Commented Dec 7, 2015 at 14:52
  • 2
    Possible duplicate of Java stopped erroring on non-final variables in inner classes (java 8) Commented Dec 7, 2015 at 14:54
  • 2
    Sounds like he has eclipse configured to target(compile to) java 1.7. This is possible even if you have java 1.8 installed because eclipse includes its own compiler Commented Dec 7, 2015 at 14:55

2 Answers 2

6

Newer java versions are more tolerant in this concern: they only require that they should be "effectively final".

At the end, the difference is not soo big - you only can use variables which you COULD tag with final; you may not modify them.

If you are at that place, you as well can make them "really" final, and it works everywhere.

BTW, on 1.8 with its new lambda syntax you can write more elegantly

button.addActionListener((ActionEvent arg0) -> jLabel.setText("xyz"));
Sign up to request clarification or add additional context in comments.

3 Comments

More specifically "effectively final" was introduced from Java 1.8... On previous versions it has to be declared as final.
@Codebender I thought so as well, but the OP seems to observe this "old" behaviour on 1.8 versions as well - if he is not wrong...
"Newer" is relative. 7 and older are EoPU, obsolete and should not be used anymore.
0

You could define the Listener not as an anonymous class but as a private inner class in order to avoid that problem:

public class Main {

    public Main(String[] args) {

        JLabel jLabel = new JLabel();
        JButton button = new JButton();
        button.addActionListener(new MyActionListener(jLabel));
    }

    private class MyActionListener implements ActionListener {

        private JLabel jLabel;
        MyActionListener(JLabel jLabel) {
            this.jLabel = jLabel;
        }

        @Override
        public void actionPerformed(ActionEvent arg0) {
            jLabel.setText("xyz");            
        }

    }
}

This way you can just pass the label (and button if you need) to the constructor of the listener and will be able to use it without any problems.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.