我正在创建一个带有seekbar的MediaPlayer.Here, mp 是一个MediaPlayer对象,而 seeker 是在MainActivity类中创建的搜索栏对象。
我的理解是,只有最终成员才能访问匿名内部类。然后 runnable如何访问这些对象(mp和搜索者)。
h = new Handler(); // create a handler for the MainActivity
//create a runnable activity to change the progress of seekbar in MainThread for every 1 sec
Runnable r = new Runnable() {
@Override
public void run() {
if (mp != null) {
seeker.setProgress(mp.getCurrentPosition() / 1000);
}
h.postDelayed(this, 1000);
}
};
this.runOnUiThread(r);
注意:代码完美无缺。感谢您的帮助。
答案 0 :(得分:4)
它发生了,因为有一种叫做有效的最终。
<强> jls-8.1.3: 强>
在内部类中使用但未声明的任何局部变量,形式参数或异常参数必须声明为final或者是有效的final(§4.12.4),否则在尝试使用时会发生编译时错误。
<强> jls-4.12.4: 强>
如果变量实际上是final,则将final修饰符添加到其声明中不会引入任何编译时错误。相反,如果删除了最终修饰符,则在有效程序中声明为final的局部变量或参数将成为最终的。
当变量只设置一次并且在内部类中使用时,编译器将变量的修饰符转换为final
。
请考虑以下代码 Tests.java:
public class Tests {
public static void main(String[] args) throws Throwable {
String value = "Hello";
Runnable runnable = new Runnable() {
@Override
public void run() {
System.out.println(value);
}
};
}
}
上面的代码在编译时会生成此代码。你能看到编译器将value
的修饰符改为final吗?
Tests.class(已解码):
public class Tests {
public Tests() {
}
public static void main(String[] args) throws Throwable {
final String value = "Hello";
Runnable var10000 = new Runnable() {
public void run() {
System.out.println(value);
}
};
}
}
但是,如果你改变变量的值(参见下面的代码),它将不会被编译,因为编译器知道它不是一个有效的最终变量:
public class Tests {
public static void main(String[] args) throws Throwable {
String value = "Hello";
value = "world";
Runnable runnable = new Runnable() {
@Override
public void run() {
System.out.println(value);
}
};
}
}