可以将变量声明为final。 最终变量只能分配一次。 如果分配了最终变量,则将导致编译时错误,除非在分配前立即将其绝对取消分配。
分配任何最终变量后,将永远无法对其进行更改。 如果变量引用任何对象的任何实例,它将继续引用相同的对象实例,但是可以修改对象的内部状态。
有效地最终
且仅当且仅当变量才可以被视为有效的最终变量
- 它不是最终的
- 分配发生一次
我发现有效地解释final的最简单方法是想象将final修饰符添加到变量声明中。 如果通过此更改,程序在编译时和运行时都继续以相同的方式运行,则该变量实际上是最终变量。
在Lamda表达式中使用
使用但未在lambda表达式中声明的任何局部变量,形式参数或异常参数必须声明为final或有效地为final,否则在尝试使用时会发生编译时错误。
将局部变量捕获限制为有效的不变变量的目的是使开发人员将注意力转移到更容易并行化的,自然线程安全的技术上。 如果管理不当,可变字段始终是潜在的并发问题来源。 禁止通过lambda表达式捕获字段将降低实用性,而无需执行任何操作。
最终关键字的使用
根据我的观点,最好在适当的时候将局部变量,方法参数,字段变量标记为final。 它警告其他开发人员不要意外修改值。 除此之外,它还向编译器发出信号以优化类文件。 有很多反对此说法的说法,即在源文件中使用final关键字不能优化类文件是不正确的。 我强烈建议您看一下Robert Simons Jr编写的Hardcore Java ,其中详细介绍了final关键字的使用及其优化。
我觉得使用final关键字会使任何开发人员都清楚代码的意图。 将变量设为final可以减轻程序员的负担,使他们可以遍历代码以查看变量在初始化后是否已更改。 就在多线程环境中维护状态而言,它也比非最终变量安全得多。
根据RustyX在StackOverflow 线程中提供的详细基准测试,以下程序演示了明显的性能提升:
public class FinalTest {
public static final int N_ITERATIONS = 10_00_000;
public static String testFinal() {
final String a = "a";
final String b = "b";
return a + b;
}
public static String testNonFinal() {
String a = "a";
String b = "b";
return a + b;
}
public static void main(String[] args) {
long tStart, tElapsed;
tStart = System.currentTimeMillis();
for (int i = 0; i < N_ITERATIONS; i++)
testFinal();
tElapsed = System.currentTimeMillis() - tStart;
System.out.println("Method with finals took " + tElapsed + " ms");
tStart = System.currentTimeMillis();
for (int i = 0; i < N_ITERATIONS; i++)
testNonFinal();
tElapsed = System.currentTimeMillis() - tStart;
System.out.println("Method without finals took " + tElapsed + " ms");
}
}
结果非常出色:
Method with finals took 5 ms
Method without finals took 273 ms
我个人也更倾向于使用不可变的类,并使用final关键字作为实例变量来表明这一点。 根据有效Java的 Joshua Bloch的说法,
不可变的类比可变的类更容易设计,实现和使用。 它们不易出错,并且更安全。。此外,不可变对象可以恰好处于一种状态,即创建该对象的状态。 vs可变对象可以具有任意复杂的状态空间。
静态代码分析工具
适当时,像PMD这样的静态分析工具是使用final关键字的最大支持者之一。 有关更多信息,请查看此 。 如果缺少final关键字,则将FindBugs和CheckStyle配置为对变量发出警告。 我发现此链接支持在Checkstyle中使用final关键字:
在执行该方法的算法期间更改参数的值可能会造成混淆,应该避免。 让Java编译器阻止这种编码样式的一种好方法是将参数声明为final。
Eclipse保存动作
Eclipse IDE提供了有用的“ 保存操作首选项”页面 ,该页面使您可以应用主要侧重于优化源代码的更改。 保存操作之一是在适当的情况下将最终关键字应用于变量。
结论
在清晰的设计和可读性方面,我支持在源文件中使用final关键字,而我的其他Java开发人员中很少有人因为它带来的视觉混乱而与我不同意。 我同意,在局部变量,实例变量,方法参数,构造函数参数,catch子句中使用final关键字似乎可以增加视觉混乱和冗长。 但是,如果有什么可以帮助任何未来的开发人员或维护人员更快,更可靠,更有效地执行其工作的,我们应该加以利用。
但是,当然,这全都是个人喜好;-)我很想听听您对此的看法。
翻译自: https://www.javacodegeeks.com/2017/07/all-about-finals.html