如果你把它放在一个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的匿名类只能引用标记为finalvariables。 这样,匿名类只需要存储重复的引用,而不需要维护对本地函数堆栈的完整访问。 例如:

 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()返回的引用,并且不允许任何其他赋值给myTextFieldvariables,即执行

 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。