如何解决当我想在 Java 的类方法中使用类字段时,定义最终局部变量是一个好习惯吗?
最近,我正在阅读 Java 源代码,例如ArrayList、arraydeque、LinkedList 等。我发现当他们想在类方法中使用某个类字段时,他们总是会声明一个等于该字段的最终局部变量。但是,如果我没有看了源码,我永远不会考虑做这件事。这样做是一个好习惯吗?或者为什么 Java Source Code 选择这样做?有什么优势,比如性能?
参考:
示例: 链表中的 getFirst()
public E getFirst() {
final Node<E> f = first;
if (f == null)
throw new NoSuchElementException();
return f.item;
}
arraydeque 中的布尔值 delete(int i)
private boolean delete(int i) {
checkInvariants();
final Object[] elements = this.elements;
final int mask = elements.length - 1;
final int h = head;
final int t = tail;
final int front = (i - h) & mask;
final int back = (t - i) & mask;
// Invariant: head <= i < tail mod circularity
if (front >= ((t - h) & mask))
throw new ConcurrentModificationException();
// Optimize for least element motion
if (front < back) {
if (h <= i) {
System.arraycopy(elements,h,elements,h + 1,front);
} else { // Wrap around
System.arraycopy(elements,1,i);
elements[0] = elements[mask];
System.arraycopy(elements,mask - h);
}
elements[h] = null;
head = (h + 1) & mask;
return false;
} else {
if (i < t) { // copy the null tail as well
System.arraycopy(elements,i + 1,i,back);
tail = t - 1;
} else { // Wrap around
System.arraycopy(elements,mask - i);
elements[mask] = elements[0];
System.arraycopy(elements,t);
tail = (t - 1) & mask;
}
return true;
}
}
解决方法
这是一个微优化,它可能对标准库代码有意义,标准库代码将被很多人使用,而阅读的人却少得多。我不建议在你自己的代码中这样做,除非性能是一个真正的问题,并且你已经分析了你的应用程序以确定代码的哪些部分是真正的瓶颈,否则性能增益可能可以忽略不计,所以主要效果将是使您的代码更加冗长。
使用局部变量应该有一些非常小的性能优势,因为:
- 局部变量将被分配在栈上或寄存器中,这比其他内存访问速度更快,因此仅从堆中进行单个字段访问肯定会最大限度地减少较慢访问的次数(充其量,访问内存在堆只能像访问局部变量一样快,但最坏的情况可能会更慢)。
- 用于访问局部变量的 bytecode instructions 较短。前四个局部变量可以使用
aload0
、aload1
、aload2
和aload3
加载,每个都是一个字节,aload
是两个字节,包括要加载的局部变量的索引。相比之下,getfield
需要三个字节,其中两个用于引用正在访问的字段。
非同步方法也可能存在语义差异,因为即使在方法执行期间该字段被另一个线程更改,局部变量也将保持相同的值。但是,您将在其中看到这种模式的大多数标准库类并不意味着是线程安全的,即使该类是为了并发,这样做也不一定使方法成为线程安全的。>
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。