final 变量 java_java-如果将“ final”放在变量之前,它会做什么?

在Java中,final关键字用于声明变量、方法或类不可变。对于变量,final确保其引用一旦赋值后不能改变,但所引用的对象的内部状态仍可变。final在并发编程中也有特殊意义,提供了一种线程安全的访问方式。此外,final在匿名内部类中是必需的,以引用外部的局部变量。
摘要由CSDN通过智能技术生成

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值