所谓的最不起眼的事情如何导致争议性的讨论,有时甚至导致激烈的辩论激烈,这不是很有趣吗? 例如,我目睹了几次场合,如何使用关键字final
引发了非常激烈的争论。 对于一个外部观察者来说,这看起来似乎是对邪恶或神圣的最终决定stake可危。
但是,必须公平地说,大多数可能的final
用例很难适应简单的对或错模式。 使用还是不使用的选择取决于经常矛盾的个人强调。
在文学中寻求建议时,唯一的中途共识似乎是最终常数定义…
class Foo {
public static final String CONSTANT = "constantValue";
}
…和约书亚·布洛赫(Joshua Bloch)的第15项:最小化可变性1 ,他建议将不可变类的所有字段都定型为final
并确保不能扩展该类(而后者不必通过final
强制实现):
public final class Foo {
private final int value;
public Foo( int value) {
this.value = value;
}
public int getValue() {
return value;
}
[...]
}
从那里意见分歧。 小罗伯特·西蒙斯 在他的《 Hardcore Java 2》一书中,整整一章都专门介绍了final
关键字,他在结尾给出了强烈的建议:“将final遍及整个代码”。 这个写得很好的章节包含许多关于通过声明变量,参数,方法或类final
将逻辑错误转换为编译时错误的优点的见解。
另一方面,罗伯特·C·马丁(Robert C. Martin)明确不同意以下陈述:“有一些对final
良好用法,例如偶尔的final
常数,但否则关键字几乎没有价值,而且会造成很多混乱” 3 。 他继续说, final
可能会遇到的错误类型通常会在他的单元测试中涵盖。
虽然我倾向于同意马丁,但我不会说席梦思通常是错的。 过去,我实际上经常自己使用final
关键字,以避免编程错误或滥用。 但是,改变主意的原因之一可能是几年前我转向TDD方法。
通过这样做,除马丁的论点之外,我注意到,如果将协作者类或其某些方法声明为final
,则通过协作者模拟实现测试隔离变得更加棘手。 由于很难将测试视为滥用 ,这使我想到了此类声明可能暗示的深远影响。 我意识到,很难预见到将没有有效的用例,这将证明扩展和覆盖是合理的。
相反,面对final
方法或类,人们有时会颇具创造力,以某种方式规避了限制,使事情可能比例如类扩展本来就糟。 因此,如今,我通常避免在类和方法声明上使用关键字,而将自己局限于文档中不希望出现的子类注释或类似内容。
在本文结束之前,我想就上述混乱的话题分享最后的想法。 为此,请查看以下代码,该代码依赖final
来确定方法范围的变量和参数:
public void doit( final String message ) {
final int value = calculate();
final Item item = create( value, message );
executorService.submit( new Runnable() {
public void run() {
handle( item );
}
} );
}
尽管代码没有多大用处,并且可以进行不同的排列,但是对于最近偶然遇到的final
代码 ,它反映了一些实际的编码风格 。 尽管这种样式可以防止在发生意外时重新分配局部变量,但它也掩盖了一个事实,即final
声明实际上是强制性的。 这是因为在匿名Runnable
实现中使用了变量item
。 下一个代码片段摆脱了不必要的声明以强调不同之处:
public void doit( String message ) {
int value = calculate();
final Item item = create( value, message );
executorService.submit( new Runnable() {
public void run() {
handle( item );
}
} );
}
权衡利弊我更喜欢最后一个变体,但我假设根据您个人的观点,IDE的功能是通过警告退出本地重新协助的能力,团队的编码约定以及,而且,而且,您可能会有充分的理由选择第一种或第二种样式,甚至更倾向于选择两者的混合。
这使我得出最终结论,那就是争论将继续下去!
- 有效的Java(第二版),第4章–类和接口,Joshua Bloch,2008年, ↩
- 顽固的Java,第2章-最后的故事,小罗伯特·西蒙斯,2004年, ↩
- 干净的代码,第16章,重构SerialDate,罗伯特·C·马丁,2009年↩
翻译自: https://www.javacodegeeks.com/2014/04/java-code-style-the-final-decision.html