我知道编译器如何解释Java中的final关键字,但我们应该如何解释它的含义呢?应该是:
1)此变量无法更改(例如内部类使用)
或
2)我不打算更改此变量(可能对成员变量有一些优化优势)。
我问的是因为我已经处理了默认情况下所有内容都被声明为final的代码(上面的选项2),在我看来,这会使关键字贬值并隐藏真正可以'的值改变!声明变量最终还有性能优势吗?
答案 0 :(得分:17)
默认情况下,所有内容都是好的东西。您对代码的可变性建模越多,就越容易理解。
在我看来,使用final
几乎不是关于性能的。它是关于对代码的其余部分进行断言(没有改变这个变量),这可以帮助读者理解代码,并且可以由编译器进行检查。
编辑:以上是我对字段的看法。对于局部变量(包括参数),当变量将用于匿名内部类时,我个人只使用final
。这与字段不同,因为:
答案 1 :(得分:6)
最终关键字应该被放弃,它应该在所有适用的情况下都是标准的,并且终结性只能通过像
这样的关键字来重新使用this_variable_will_change_unexpectedly_behind_your_back
此关键字不应由任何IDE自动完成,并且无法使用Ctrl-V插入它。
答案 2 :(得分:4)
我刚才写了a post about this。
Final有助于阅读代码:
通过使用final,您可以告诉编译器有关您的代码的信息,它可以帮助您回报。
答案 3 :(得分:1)
第二个选项是一个安全措施。它会阻止您意外更改或重新分配。因此,提供它很有用,您可以在决定要更改变量时将其删除。
答案 4 :(得分:1)
我不能对Jon已经说过的内容添加太多内容,但为了完整起见,JLS 17.5.3说最终字段也可能导致优化;
如果在字段声明中将final字段初始化为编译时常量表达式(第15.28节),则可能无法观察到对最终字段的更改,因为在编译时将使用该最终字段的替换常量表达式的值。
答案 5 :(得分:0)
我不明白为什么你认为缺乏价值。
当我看到所有最终变量时,它意味着该类是不可变的。这是一件好事,因为不可变类本质上是线程安全的。
答案 6 :(得分:0)
一般来说,最终变量为a good thing。请注意,它只表示该变量无法重新分配,但如果变量是可变的,则指向的对象可以更改。
表现明智,final
允许更具侵略性的compiler optimisations:
规范允许对最终字段进行积极优化。在一个线程中,允许使用构造函数中不发生的最终字段的那些修改来重新排序最终字段的读取。
答案 7 :(得分:0)
将每个变量声明为final
并不会使final
关键字贬值。它可以帮助开发人员调试应用程序,以排除变量修改的可能性,尤其是在多线程应用程序环境中。
在Java 8发布版中,我们还有一个名为“ effectively final variable
”的概念
从lambda表达式引用的局部变量必须是最终的或有效的最终
如果在本地块中初始化后未修改变量,则将变量视为 有效最终 。这意味着你现在可以在匿名类或lambda表达式中使用没有final关键字的局部变量,前提是它们必须是有效的最终版本。
如果您不想将有效的final声明为final变量,那么这个新功能可以帮助您使用lambda表达式/匿名类。您可以避免为final
变量声明effective final
关键字。看看这个article
答案 8 :(得分:-1)
确实使用了最终变量,因此没有人可以更改值,它在java中作为常量。
让我举个例子
我创建了一个可以被其他人使用的包,现在有一些配置变量需要设置才能正确运行它。让我们说它的登录包。所以加密选项很少,比如
encryption_method = HASH_ENCRYPTION
OR
encryption_method = SYMMETRIC_ENCRYPTION
而不是传递整数1,2,3我们可以定义最终变量,这有助于开发人员以更易读的形式和源代码我不希望用户更改它所以我保持最终,否则内部逻辑可能会中断