0

i have a simple question about the modifier "final" and the var being used in the run() method. here is a piece of some code that i have but the else doesn't work. i guess it cant add onto the firstTime var, im not sure if this is because you cant do this with final modifiers or if java just hates me :/

final long firstTime = System.currentTimeMillis();

WorldTasksManager.schedule(new WorldTask() {
@Override
public void run() {
    if (System.currentTimeMillis() >= firstTime) {
        stop();
    } else {
    firstTime += 5;
    }
}

if you guys know whats causing this or how i can fix this, please help.

thanks in advance!

4 Answers4

2

Final variables cannot be modified. That is (essentially) the definition of final.

You can't change the reference, but you can mutate the object. However, in the case of long like you have here, a new long is created and assigned to the value of firstTime, which is attempting to change the reference and thereby illegal.

Jon Newmuis
  • 25,722
  • 2
  • 45
  • 57
  • when I tried to remove the final modifier I got another error. to fix it all I had to do was declare the long, firstTime, inside worldtask and it worked like a charm – user1596097 Aug 18 '12 at 00:19
1

A final variable can only be assigned in the constructor or at declaration time through an initializer.

Razvan
  • 9,925
  • 6
  • 38
  • 51
1

This SO Q&A explains the compilation error you got when you removed the final modifier:

In your example, the firstTime that the run() variable sees is actually a copy of the firstTime variable in the enclosing class. The final is required to preserve the illusion that there is only one variable ...

Your solution of moving the declaration of firstTime into the run() method is good, but it does change the behaviour. The variable is now set to the time when the task starts running, were previously it was set to the time when the task was scheduled.

Finally, if you really want the run() method to be able to update the firstTime variable in the enclosing scope, you are going to need to do this some other way. This simplest way would be to make firstTime an instance variable, not a local variable. You could then remove the final and the run() method could update the variable directly.

Community
  • 1
  • 1
Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
0

Do it like

WorldTasksManager.schedule(new WorldTask() {
@Override
public void run() {
    long firstTime = System.currentTimeMillis();
    if (System.currentTimeMillis() >= firstTime) {
        stop();
    } else {
    firstTime += 5;
    }
}
Bharat Sinha
  • 13,973
  • 6
  • 39
  • 63