【发布时间】:2010-10-25 02:29:21
【问题描述】:
非常基本的问题,但是,如果将“final”放在下面的变量之前会做什么......
final EditText myTextField = (EditText) findViewById(R.id.myTextField);
final 是做什么的?
【问题讨论】:
-
好吧!我想我得到了答案! (6 个答案!哇!)所有这些工作。
标签: java
非常基本的问题,但是,如果将“final”放在下面的变量之前会做什么......
final EditText myTextField = (EditText) findViewById(R.id.myTextField);
final 是做什么的?
【问题讨论】:
标签: java
简答
停止将“myTextField”变量分配给其他对象。
长答案
由于上述原因,我总是尽可能将“final”修饰符应用于静态字段、实例字段、局部变量和方法参数。它确实使代码有点膨胀,但对我来说,额外的可读性和健壮性是值得的。
【讨论】:
关键字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);
【讨论】:
其他答案都没有注意到的一件事是 final 属性相对于 Java 内存模型具有特殊属性。最终效果是一个线程可以安全地访问final 属性的值,而无需采取步骤与其他线程同步。
跟进
这是 JVM 特有的吗?
Java 内存模型的规范是 Java 语言规范的一部分,并且 (AFAIK) 自 Java 1.5 以来没有改变。从这个意义上说,这不是 JVM 特定的。
但是,如果您不遵守规则(即,如果您的代码未正确同步其对共享数据的使用),Java 的行为取决于各种因素,包括您运行应用程序的硬件。
除其他外,Java 内存模型旨在允许多核机器运行许多 Java 线程,而不必不断刷新内存缓存......这会降低性能。基本上,它指定了一些规则来保证一个 Java 线程可以看到来自另一个线程的内存更新。如果应用程序不遵守规则,可能线程将看到由其他线程写入的某些字段的陈旧(过期)值,从而导致偶尔出现未定义的行为。 p>
【讨论】:
final 关键字将确保 myTextField 持有任何 findViewByID() 返回的引用,并禁止对 myTextField 变量的任何其他赋值,即在执行之后
final EditText myTextField = (EditText) findViewById(R.id.myTextField);
如果您尝试为 myTextField 分配任何值,您将收到编译器错误。
【讨论】:
myTextField 的引用一旦分配就无法修改。更多信息来自Wikipedia
最终变量只能赋值 一次。此任务不授予 变量不可变状态。如果 变量是类的一个字段,它 必须在构造函数中赋值 它的类。 (注:如果变量是 参考,这意味着 变量不能重新绑定到 引用另一个对象。但是 它引用的对象仍然是 可变的,如果它最初是 可变的。)与 a 的值不同 常量,final的值 变量不一定是已知的 编译时间。
【讨论】:
如果一个变量被标记为final,那么该变量的值就不能改变,即当与变量一起使用时,final 关键字使其成为一个常量。如果您在程序执行过程中尝试更改该变量的值,编译器会给您一个错误。
【讨论】:
关键字final 将myTextField 声明为常量变量。
【讨论】:
试图用代码流解释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
【讨论】: