Why do variables passed to runnable need to be final?

user485498 picture user485498 · Jul 11, 2012 · Viewed 12.8k times · Source

If I have a variable int x = 1, say, and I declare a runnable in the main thread, and I want to pass x to the runnable's run() method, it must be declared final. Why?

final int x = 0;//<----must be final...
private class myRun implements Runnable {

    @Override
    public void run() {
        x++;//
    }

}

Answer

jacobm picture jacobm · Jul 11, 2012

Because that's what the language specification says. According to Guy Steele, the rationale behind this choice is that programmers would expect the declaration int x = 0 in a method to result in stack-allocated storage, but if you can return a new myRun() from the method (or otherwise let a myRun persist past the function's return) and you can modify it afterwards, then x has to be heap-allocated instead to have the semantics you'd expect.

They could have done that, and in fact other languages have done it that way. But the Java designers decided instead to require that you mark x as final to avoid requiring implementations to heap-allocate what looks like stack-allocated storage.

(I should note: this isn't specific to Runnable. It applies to any anonymous inner class.)