在Android中如果我正在更新侦听器内的变量,例如onDragListener,如果在方法中声明它,我需要将变量设为final。
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();
}
}
});
}
或者如果它不在方法之外,则不需要是最终的。
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();
}
}
});
}
我很好奇为什么在方法中需要最终结果,但不在方法之外。任何人都可以对此有所了解吗?
答案 0 :(得分:4)
在Java
中,匿名内部类只能引用封闭范围内的final
个变量。
请参阅the doc.
从Java 8开始,如果变量"实际上是最终的" 就足够了,这意味着你不需要明确地声明它为final
,但只有在尝试重新分配从匿名内部类访问的变量时才会出现编译器错误。
答案 1 :(得分:1)
这与方法无关。重要的是内在阶级。你不能在java Inner类中引用非final变量。根据{{3}}
使用但未在内部类中声明的任何局部变量,形式参数或异常参数必须声明为final。
答案 2 :(得分:1)
当在方法体内定义匿名内部类时,可以从内部类中访问在该方法范围内声明为final的所有变量。对于标量值,一旦分配了标量值,最终变量的值就不会改变。对于对象值,引用不能更改。这允许Java编译器捕获"运行时变量的值,并将副本存储为内部类中的字段。一旦外部方法终止并且其堆栈框架已被移除,原始变量就消失了,但内部类的私有副本仍然存在于类的自己的内存中。
答案 3 :(得分:1)
更详细的原因:
因此,基本上Java编译器不允许您引用可能被清除的局部变量。
当将变量更改为final时,它们将成为常量,编译器将在编译类时知道如何设置它们的值。
答案 4 :(得分:-5)
Java中的final关键字。这就是全部。