java-如果将“ final”放在变量之前,它会做什么?
一个非常基本的问题,但是,如果将“ final”放在诸如下面的变量之前,它会做什么?
final EditText myTextField = (EditText) findViewById(R.id.myTextField);
final是做什么的?
Jack Love asked 2020-07-29T09:35:44Z
8个解决方案
70 votes
简短答案
停止将“ myTextField”变量分配给其他对象。
长答案
不会阻止“ myTextField”变量发生突变,例如 将其字段设置为新值。
使代码更具可读性(IMHO),因为读者不必怀疑以后是否会在代码中重新分配“ myTextField”变量。
防范错误类别(错误地重新分配变量)的错误类别(使实例不可变的背后相同原因,仅在较小的范围内)。
由于上述原因,我总是在可能的情况下始终将“ final”修饰符应用于静态字段,实例字段,局部变量和方法参数。 它确实使代码有些膨胀,但是对我来说值得额外的可读性和鲁棒性。
Andrew Swan answered 2020-07-29T09:36:22Z
15 votes
在这种情况下,关键字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);
Michael Aaron Safyan answered 2020-07-29T09:36:47Z
10 votes
其他答案都没有指出的一件事是final属性相对于Java内存模型具有特殊的属性。 最终结果是,一个线程可以安全地访问2987648406212052051969属性的值,而无需采取与其他线程同步的步骤。
跟进
该JVM是否特定?
Java内存模型的规范是Java语言规范的一部分,并且(AFAIK)自Java 1.5起就没有更改。 从这个意义上讲,这不是JVM特定的。
但是,如果您不遵守规则(即,如果您的代码未正确同步其对共享数据的使用),则Java的行为取决于各种情况,包括运行应用程序的硬件。
Java内存模型尤其设计为允许多核计算机运行许多Java线程,而不必不断刷新内存缓存……这会降低性能。 基本上,它指定一些规则,这些规则将保证一个Java线程可以从另一个线程看到内存更新。 如果应用程序不遵循规则,则线程可能会看到某个其他线程写入的某个字段的陈旧(过期)值,从而导致偶然的不确定行为。
Stephen C answered 2020-07-29T09:37:30Z
4 votes
final关键字将确保myTextField保留对findViewByID()返回的任何内容的引用,并禁止对myTextField变量进行任何其他赋值,即在执行完之后。
final EditText myTextField = (EditText) findViewById(R.id.myTextField);
如果尝试为myTextField分配任何值,则会出现编译器错误。
Suresh Kumar answered 2020-07-29T09:37:54Z
3 votes
myTextField的引用一旦分配即无法修改。 以下来自维基百科的更多信息
最终变量只能分配 一旦。 此分配不授予 可变的不可变状态。 如果 变量是类的字段,它 必须在的构造函数中分配 它的班级。 (注意:如果变量是 参考,这意味着 变量不能重新绑定到 引用另一个对象。 但是 它引用的对象仍然 可变的,如果它最初是 可变。)与a的值不同 常数,最终值 变量不一定在 编译时间。
rkg answered 2020-07-29T09:38:19Z
3 votes
如果将变量标记为final,则该变量的值无法更改,即与变量一起使用时,final关键字使其变为常数。 而且,如果您在程序执行过程中尝试更改该变量的值,则编译器将给您一个错误。
farhankhwaja answered 2020-07-29T09:38:40Z
2 votes
关键字final将myTextField声明为常量。
irrelephant answered 2020-07-29T09:39:00Z
0 votes
尝试通过代码流来解释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
nabster answered 2020-07-29T09:39:24Z