1

In Android if I'm updating a variable inside a listener, e.g. onDragListener, I either need to make the variable final if it's declared inside the method.

private void myMethod() {
   final int[] something = {null};

   mf.setOnDragListener(new TouchableWrapper.OnDragListener() {
       @Override
       public void onDrag(MotionEvent motionEvent) {

           map.setMyLocationEnabled(false);
           Log.d("Map", "Stopped location and remove drag listener");
           if (motionEvent.getActionMasked() == MotionEvent.ACTION_UP) {

               //Stop restartLocation if it's running

               if (restart[0] != null) {
                   restart[0].cancel = true;
               }
               restart[0] = new RestartLocation();
               restart[0].start();
           }
       }
   });
}

Or if it's outside of the method it doesn't need to be final.

private RestartThread restart;
private void myMethod() {


   mf.setOnDragListener(new TouchableWrapper.OnDragListener() {
       @Override
       public void onDrag(MotionEvent motionEvent) {

           map.setMyLocationEnabled(false);
           Log.d("Map", "Stopped location and remove drag listener");
           if (motionEvent.getActionMasked() == MotionEvent.ACTION_UP) {

               //Stop restartLocation if it's running

               if (restart != null) {
                   restart.cancel = true;
               }
               restart = new RestartLocation();
               restart.start();
           }
       }
   });
}

I'm curious as to why the final is needed inside the method, but not outside of the method. Can anyone shed some light on this?

TMH
  • 6,096
  • 7
  • 51
  • 88
  • I think this question is related to [Why are only final variables accessible in anonymous class?](http://stackoverflow.com/questions/4732544/why-are-only-final-variables-accessible-in-anonymous-class) – Vikas V Apr 07 '14 at 10:26

5 Answers5

4

In Java, anonymous inner classes can refer only to finalvariables in the enclosing scope.

See the doc.

From Java 8 onwards, it would be enough if the variable is "effectively final", meaning you are not required to explicitly declare it as final, but will get a compiler error only if you attempt to reassign a variable that is accessed from anonymous inner class.

senseiwu
  • 5,001
  • 5
  • 26
  • 47
  • Thanks to everyone for the answers, that makes sense now, I never thought about the Class. I can't accept an answer for a few more minutes but when the times up I will accept this, cheers! – TMH Apr 07 '14 at 10:29
1

It's not related to method. It is the inner class that matter. you cannot refer to non-final variable inside a java Inner class. according to spec

Any local variable, formal parameter, or exception parameter used but not declared in an inner class must be declared final.

stinepike
  • 54,068
  • 14
  • 92
  • 112
1

When an anonymous inner class is defined within the body of a method, all variables declared final in the scope of that method are accessible from within the inner class. For scalar values, once it has been assigned, the value of the final variable cannot change. For object values, the reference cannot change. This allows the Java compiler to "capture" the value of the variable at run-time and store a copy as a field in the inner class. Once the outer method has terminated and its stack frame has been removed, the original variable is gone but the inner class's private copy persists in the class's own memory.

From Wikipedia

QuarK
  • 2,306
  • 1
  • 20
  • 24
1

The more detailed reason:

  • You created an anonymous inner class
  • The class instance may live after the scope of the method in which you defined it
  • Local variables scope (of methods) is limited to the specific method.

So, basically the Java compiler will not let you refer to local variables that may be cleared.

When changing the variables to final they become constants and the compiler will know how to set their values when compiling the classes.

Uri Lukach
  • 1,093
  • 1
  • 14
  • 28
-5

final keyword in Java before a data means data is to be treated as constant. That's all.

Dr. Debasish Jana
  • 6,980
  • 4
  • 30
  • 69