如果你把它放在一个variables之前,“final”是做什么的?
非常基本的问题,但是,如果你把它放在variables之前,“final”是做什么的…
final EditText myTextField = (EditText) findViewById(R.id.myTextField);
final
做什么?
简答
停止将“myTextField”variables分配给别的东西。
长答案
- 不会停止正被突变的“myTextField”variables,例如将其字段设置为新值。
- 使代码更具可读性(恕我直言),因为读者不必怀疑“myTextField”variables是否将被重新分配在代码中。
- 防止variables被意外地重新分配的错误类别(在使得实例不变的情况下相同的推理,仅在更小的范围内)。
出于上述原因,我总是将“final”修饰符应用于静态字段,实例字段,局部variables和方法参数。 它确实让代码膨胀了一点,但是对我来说这值得额外的可读性和鲁棒性。
关键字final
,在这种情况下,意味着你不能更新隐式指针myTextField
指向一个不同的对象(尽pipe你可以修改myTextField
指向的对象)。 关键字也可以用来防止重写(当应用于类或方法时)。
你可能会看到这个的一个原因是,引用局部variables的匿名类只能引用标记为final
variables。 这样,匿名类只需要存储重复的引用,而不需要维护对本地函数堆栈的完整访问。 例如:
Runnable r = new Runnable() { public static void run() { // do something with myTextField // this would require myTextField to have been marked final. }}; doSomethingLater(r);
其他答案都没有提到的一件事是final
属性与Java内存模型相比具有特殊的属性。 最终效果是一个线程可以安全地访问final
属性的值,而不需要采取步骤与其他线程同步。
跟进
那个JVM是特定的吗?
Java内存模型的规范是Java语言规范的一部分,自Java 1.5以来,(AFAIK)并没有改变。 从这个意义上讲,这不是JVM特有的。
然而,如果你不遵守规则(即,如果你的代码没有正确地同步它对共享数据的使用),Java的行为取决于各种各样的事情,包括你运行应用程序的硬件。
除此之外,Java内存模型旨在允许多核机器运行多个Java线程,而不必连续刷新内存caching……这会导致性能下降。 基本上,它指定了一些规则来保证一个Java线程看到来自另一个线程的内存更新。 如果应用程序不遵循规则,则某个线程可能会看到某个其他线程写入的某个字段的陈旧(过期)值,从而导致偶然的未定义行为。
final
关键字将确保myTextField
持有任何findViewByID()返回的引用,并且不允许任何其他赋值给myTextField
variables,即执行
final EditText myTextField = (EditText) findViewById(R.id.myTextField);
如果您尝试将任何值分配给myTextField,您将得到一个编译器错误。
分配完毕后,您无法修改myTextField
的引用。 从维基百科下面的更多信息
最后的variables只能分配一次。 此分配不会授予variables不可变状态。 如果variables是一个类的字段,它必须在它的类的构造函数中进行赋值。 (注意:如果variables是一个引用,这意味着该variables不能被重新绑定来引用另一个对象,但是它引用的对象仍然是可变的,如果它最初是可变的)。与常量的值不同,最终variables的值在编译时不一定是已知的。
如果一个variables被标记为final,则该variables的值不能被改变,即,当与variables一起使用时,final关键字使其成为常量。 如果您在程序过程中尝试更改该variables的值,编译器会给您一个错误。
关键字final
myTextField
声明为一个常量variables。