Search code examples
javaattributesanonymous-methods

Why variables have to be final in anonymous methods and class fields don't


If I had this anonymous method I should declare x variable as final.

private void testMethod (ListField<BeanModel> listField){

     final ListLoader<BeanModel> loader = new PagedListLoader<BeanModel>();
     listField.addListener(Events.Attach, new Listener<ListViewEvent<BeanModel>>() {

            @Override
            public void handleEvent(ListViewEvent<BeanModel> be) {
                loader.load();
            }
          });
}

However, if loader was a class field, it wouldn't be necessary to declare it as final:

public class testClass{

    private ListLoader<BeanModel> loader = new PagedListLoader<BeanModel>();

    private void testMethod (ListField<BeanModel> listField){
        listField.addListener(Events.Attach, new Listener<ListViewEvent<BeanModel>>() {

                    @Override
                    public void handleEvent(ListViewEvent<BeanModel> be) {
                        loader.load();
                    }
                  });

        //Could I modify loader's reference here, before the method executes?
        //loader = null;
        }
}

Does anyone know the reason why they guarantee local variables not to change when they're accessed but don't do it for class fields?


Solution

  • The local variable is allocated in the stack, and it will fall out of scope after testMethod(). Making the variable final ensures that it is ok to just pass a reference to it to the anonymous class. If it was not final, a later assignment to it in testMethod() could change the value later with confusing results. (The user might expect the later assigned value used, but that would be impossible).

    A field of the parent class, however can be accessed through the parent reference of the anonymous class, so any later assignments can be handled without confusion.