/**
* Retrieves and removes the head (first element) of this list.
*
* @return the head of this list, or {@code null} if this list is empty
* @since 1.5
*/
public E poll() {
final Node<E> f = first; //why final here? <<-------- ******* --------
return (f == null) ? null : unlinkFirst(f);
}
您好,我正在阅读JDK 1.7的源代码。在LinkedList.java的上面代码片段中,我无法理解为什么需要&#39; final&#39;在poll()方法中。为什么不:
public E poll() {
return (first == null) ? null : unlinkFirst(first);
}
您能分享实施的见解吗?感谢。
答案 0 :(得分:3)
LinkedList中的大多数方法都使用局部变量的final
声明。
这可能与Using "final" modifier whenever applicable in java背后的概念有关。
为所有不应更改的内容添加final可以简化您(或下一个程序员,处理代码)会误解或误用导致代码的思维过程的可能性。至少它应该响起一些钟声,因为他们现在想要改变你以前不变的东西。
从技术上讲,以6个字母为代价,您保证您永远不会发生变化的事情永远不会改变。
您建议的代码是否有效? 是的。我没有看到任何情况。它在程序上有效。
然而,在整个代码中使用final
支持完整性测试,并且可以理解的是,对于我们在Java中完成所有事情的所有util
内容,它都是很高兴知道一切都按预期工作。
注意:如果存在我未见过的安全问题,我会有兴趣在单独的答案中了解这一点。
答案 1 :(得分:3)
Martin Buchholz在相关问题的concurrency-interest列表中回答了这个问题:
我们在jsr166-land认为我们的软件足够重要 我们不建议常规java程序员优化。复制最终版 字段到本地生成较小的字节码,可能有助于jit生成 更好的代码(以及当前的热点,仍然如此)。
在本地人身上使用final没有性能优势,但确实有一些优势 软件工程优势。我们倾向于将它用于具有相同的本地人 将字母命名为字段,例如
final Foo foo = this.foo;
答案 2 :(得分:2)
指南针的回答非常合理,但我只想补充一点猜测。我认为这是微优化,因为对本地变量f
的访问平均应该比访问类字段first
更快。最终修饰符是良好实践,但不会影响访问延迟。在这种特定情况下,增益可能非常小,因为您正在为单个类字段访问和两个局部变量访问交换两个类字段访问。
这不是你应该在日常编程中做的事情,但由于集合库基本上都是由现有的每个Java程序使用,因此这些东西在这里是合理的。