非常基本的问题,但是,如果你把它放在一个变量之前,那么“最终”会做什么呢......
final EditText myTextField = (EditText) findViewById(R.id.myTextField);
final
做了什么?
答案 0 :(得分:70)
简答
停止将“myTextField”变量分配给其他内容。
长答案
由于上面给出的原因,我总是将“final”修饰符应用于静态字段,实例字段,局部变量和方法参数。它确实使代码膨胀了一点,但对我来说,值得额外的可读性和稳健性。
答案 1 :(得分:15)
在此上下文中,关键字final
表示您无法将隐式指针myTextField
更新为指向其他对象(尽管您可以修改myTextField
指向的对象) 。关键字也可用于防止覆盖(当应用于类或方法时)。
您可能会看到这一点的一个原因是引用局部变量的匿名类只能引用标记为final
的变量。这样,匿名类只需要存储重复的引用,而不需要保持对本地函数堆栈的完全访问。例如:
Runnable r = new Runnable() { public static void run() {
// do something with myTextField
// this would require myTextField to have been marked final.
}};
doSomethingLater(r);
答案 2 :(得分:10)
其他答案都没有注意到的一点是final
属性与Java内存模型相比具有特殊属性。实际效果是,一个线程可以安全地访问final
属性的值,而无需采取步骤与其他线程同步。
<强>后续强>
JVM是否具体?
Java内存模型的规范是Java语言规范的一部分,自Java 1.5以来,(AFAIK)没有改变。从这个意义上说,这不是JVM特有的。
但是,如果您不遵守规则(即,如果您的代码未正确同步其共享数据的使用),Java的行为取决于各种各样的事情,包括您运行应用程序的硬件。
除此之外,Java内存模型旨在允许多核机器运行许多Java线程,而无需不断刷新内存缓存......这会破坏性能。基本上,它指定了一些规则,可以保证一个Java线程从另一个线程看到内存更新。如果应用程序不遵循规则,则可能线程将看到某些其他线程写入的某些字段的陈旧(过时)值,从而导致偶尔出现未定义的行为。
答案 3 :(得分:4)
final
关键字将确保myTextField
保存findViewByID()返回的引用,并禁止对myTextField
变量进行任何其他分配,即在执行
final EditText myTextField = (EditText) findViewById(R.id.myTextField);
如果您尝试将任何值分配给myTextField,您将收到编译器错误。
答案 4 :(得分:3)
分配后,您无法修改myTextField
的引用。以下来自Wikipedia
只能分配最终变量 一旦。此作业不授予 变量不可变状态。如果 变量是类的一个字段,它 必须在构造函数中赋值 它的班级。 (注意:如果变量是a 参考,这意味着 变量无法重新绑定 引用另一个对象。但是 它引用的对象仍然是 可变的,如果它是最初的 可变的。)与a的价值不同 常数,最终的价值 变量不一定是已知的 编译时间。
答案 5 :(得分:3)
如果变量标记为 final ,那么该变量的值不能更改,即与变量一起使用时,final关键字使其成为常量。如果您尝试在程序过程中更改该变量的值,编译器将给您一个错误。
答案 6 :(得分:2)
关键字final
将myTextField
声明为常量变量。
答案 7 :(得分:0)
尝试通过代码流来说明final
修饰符的使用:
public static void main(String[] args) {
class Person {
String name;
}
Person peep1 = new Person(); // points to obj at address HEX001
peep1.name = "Mike";
System.out.println(peep1.name);
Person peep2 = new Person(); // points to obj at address HEX002
peep2.name = "Jenna";
System.out.println(peep2.name);
final Person peep3 = peep1; // also points to obj at address HEX001
System.out.println(peep3.name);
peep1.name = "pwnd"; // modifies obj at address HEX001
System.out.println(peep1.name);
System.out.println(peep3.name);
peep1 = peep2; // now it points to obj at address HEX002
System.out.println(peep1.name);
System.out.println(peep3.name); // still points to obj at address HEX001
peep2.name = "Henna"; // modifies obj at address HEX002
System.out.println(peep2.name);
peep3 = peep2; // compiler error "The final local variable peep3 cannot be assigned. It must be
// blank and not using a compound assignment"
System.out.println(peep3.name); // assuming it now points to obj at address HEX002
}
输出:
Mike
Jenna
Mike
pwnd
pwnd
Jenna
pwnd
Henna