Java 什么是;“最后的”;如果你把它放在变量之前,你会怎么做?
非常基本的问题,但是,如果你把“final”放在一个变量之前,比如下面,它会做什么呢Java 什么是;“最后的”;如果你把它放在变量之前,你会怎么做?,java,Java,非常基本的问题,但是,如果你把“final”放在一个变量之前,比如下面,它会做什么呢 final EditText myTextField = (EditText) findViewById(R.id.myTextField); final做什么?简短回答 停止将“myTextField”变量分配给其他变量 长答案 不会停止“myTextField”变量的变异,例如将其字段设置为新值 使代码更具可读性(IMHO),因为读者永远不必怀疑“myTextField”变量是否会在代码中重新分配 防止
final EditText myTextField = (EditText) findViewById(R.id.myTextField);
final
做什么?简短回答
停止将“myTextField”变量分配给其他变量
长答案
- 不会停止“myTextField”变量的变异,例如将其字段设置为新值
- 使代码更具可读性(IMHO),因为读者永远不必怀疑“myTextField”变量是否会在代码中重新分配
- 防止意外重新分配变量的错误类别(使实例不可变的原因相同,只是规模较小)
出于上述原因,我总是尽可能地将“final”修饰符应用于静态字段、实例字段、局部变量和方法参数。它确实使代码膨胀了一点,但对我来说,它值得额外的可读性和健壮性。一旦分配了
myTextField
的引用,您就不能修改它。更多信息请访问
只能指定最终变量
一旦此任务不授予
变量为不可变状态。如果
变量是类的一个字段,它
必须在的构造函数中指定
它的等级。(注意:如果变量为
参考,这意味着
无法将变量重新绑定到
引用另一个对象。但是
它引用的对象仍然是
可变的,如果它最初是
与a的值不同
常数,最终值
变量不一定是已知的
编译时
在此上下文中,关键字
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
将myTextField
声明为常量变量。关键字final
将确保myTextField
保存findViewByID()返回的任何内容的引用,并禁止对myTextField
变量进行任何其他赋值,即在执行
final EditText myTextField = (EditText) findViewById(R.id.myTextField);
如果您尝试为myTextField赋值,您将得到一个编译器错误。其他答案都没有提到的一点是,
final
属性相对于Java内存模型具有特殊属性。净效果是一个线程可以安全地访问final
属性的值,而无需采取步骤与其他线程同步
跟进
这是JVM特有的吗
Java内存模型的规范是Java语言规范的一部分,并且(AFAIK)自Java1.5以来没有改变。从这个意义上讲,这不是JVM特有的
但是,如果您不遵守规则(即,如果您的代码没有正确同步其对共享数据的使用),Java的行为取决于各种情况,包括运行应用程序的硬件
除此之外,Java内存模型的设计允许多核机器运行多个Java线程,而无需不断刷新内存缓存。。。这将扼杀性能。基本上,它指定了一些规则来保证一个Java线程看到来自另一个线程的内存更新。如果应用程序不遵循规则,则线程可能会看到由其他线程编写的某个字段的过时(过期)值,导致偶尔出现未定义的行为。如果变量被标记为final,则该变量的值不能更改,即final关键字在与变量一起使用时使其成为常量。如果您在编程过程中试图更改该变量的值,编译器将给您一个错误。试图解释
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
好!我想我得到了答案!(6个答案!哇!)所有这些工作。如果它提供了有用的功能,我就不认为它是臃肿的。我想我知道最后的足够了,但现在我意识到我必须知道更多。不,在JMM里@安德森-我刚才说:-)机械的重复被低估了@斯蒂芬:很明显,我的拼写练习包括不充分的死记硬背。@andersoj-或者换句话说,你的气味难闻:-)