2

Sorry for asking such a basic question, but I just can't figure it out and I have no idea how to search for it.

I have the following code:

letters = new ArrayList<JButton>();
String[] abc = new String[] {"A", "Á", "B", "C", "D", "E", "É", "F", "G", "H", "I", "Í", "J", "K", "L", "M", "N", "O", "Ó", "Ö", "Ő", "P",
        "Q", "R", "S", "T", "U", "Ú", "Ü", "Ű", "V", "W", "X", "Y", "Z" };
for (Object o: abc)
{
    letters.add(new JButton((String)o));
    int i = letters.size() - 1;
    letters.get(i).setBounds(i%10 * 60 + 40, 350 + ((i / 10) * 50), 55, 45);
    letters.get(i).addActionListener(new ActionListener()
    {
        public void actionPerformed(ActionEvent event)
        {
            System.out.println(o);
        }
    });
    mF.add(letters.get(i));
}

As you can see, I have a for loop and I'd like to use its variable 'o' inside the function. How can I do that? It says:

java: local variable o is accessed from within inner class; needs to be declared final

What exactly does this mean?

2
  • 3
    make it final, for (final Object o: abc) Commented Jun 11, 2013 at 9:18
  • Define one final object and use that object to iterate loop Commented Jun 11, 2013 at 9:19

5 Answers 5

3

In the for loop, write like this:

for (final Object o: abc)
{
    ...

So the compiler knows that the object o will not change, i.e. you will not assign a new value to it with =.

Sign up to request clarification or add additional context in comments.

Comments

3

It means that to be accessed in an inner class, the compiler has to be sure that this variable cannot be modified, as the code will be probably be executed asynchronously. change for (Object o: abc) to for (final String o: abc)

Comments

2

you can not perform System.out.println(o);

as o is not defined as final.

for (final Object o: abc)

Comments

2
letters.get(i).addActionListener(new ActionListener()
{
    public void actionPerformed(ActionEvent event)
    {
        System.out.println(o);
    }
});

Is creating an inner class, simply make the foreach loop use final Object o.

3 Comments

it is not the array instantiation that is creating an inner class, it is the new ActionListener ...
quite sure, yes. new String[] {"A", ....} is just creating an instance, not a Class, new ActionListener(... does as he is overriding actionPerformed method
@gma you are aboslutely right, I was thinking of double brace initialization
1

You are using an anonymous inner class, and from within those classes you may access final variables declared outside. Here's an example which will not work because message is not final:

public void myMethod() {
    String message = "You can't see me";

    new SomeInterface() {

        //SomeInterface declares this method:
        public void someMethod() {
            System.out.println(message); //this will not compile
        }
    };
}

But this will work because message is final:

public void myOtherMethod() {
    final String message = "You can see me now!";

    new SomeInterface() {

        //SomeInterface declares this method:
        public void someMethod() {
            System.out.println(message); //this will work!
        }
    };
}

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.