11 java variables final runnable
如果我有一个变量int x = 1,比如说,我在主线程中声明了一个runnable,并且我想将x传递给runnable的run()方法,那么必须声明它final.为什么?
final int x = 0;//<----must be final...
private class myRun implements Runnable {
@Override
public void run() {
x++;//
}
}
Run Code Online (Sandbox Code Playgroud)
jac*_*obm 10
因为这就是语言规范所说的.根据Guy Steele的说法,这个选择背后的基本原理是程序员会期望int x = 0一个方法中的声明导致堆栈分配存储,但是如果你可以new myRun()从方法中返回一个(或者让一个myRun持久化的函数返回)并且你之后可以对其进行修改,然后x必须进行堆分配,以获得您期望的语义.
他们本可以做到这一点,事实上其他语言就是这样做的.但是Java设计者决定要求你标记x为final避免要求实现堆分配看起来像堆栈分配的存储.
(我应该注意:这不是特定于Runnable.它适用于任何匿名内部类.)
Joh*_*ohn 10
因为如果它们能够被改变,它可能会导致很多问题,请考虑这个:
public void count()
{
int x;
new Thread(new Runnable()
{
public void run()
{
while(x < 100)
{
x++;
try
{
Thread.sleep(1000);
}catch(Exception e){}
}
}
}).start();
// do some more code...
for(x = 0;x < 5;x++)
for(int y = 0;y < 10;y++)
System.out.println(myArrayElement[x][y]);
}
Run Code Online (Sandbox Code Playgroud)
这是一个粗略的例子,但你可以看到可能发生很多无法解释的错误.这就是变量必须是最终的原因.以下是针对上述问题的简单修复:
public void count()
{
int x;
final int w = x;
new Thread(new Runnable()
{
public void run()
{
int z = w;
while(z < 100)
{
z++;
try
{
Thread.sleep(1000);
}catch(Exception e){}
}
}
}).start();
// do some more code...
for(x = 0;x < 5;x++)
for(int y = 0;y < 10;y++)
System.out.println(myArrayElement[x][y]);
}
Run Code Online (Sandbox Code Playgroud)
如果你想要一个更完整的解释,它有点像同步.Java希望阻止您从多个线程引用一个Object.这里有一点关于同步:
希望这有帮助!