先上图
- 当我看到这代码的时候,很奇怪为什么不直接用 this.items[putIndex] = x; 难道这样做效率更高?
- 并不仅仅是 ArrayBlockingQueue ,还有 很多集合类,只要涉及到 set ,put 方法的 ,基本都是这样类似的 做法;
- 先解释这个问题,可以从底层的字节码入手,看个例子;
final Object[] items = new Object[10];
public void test() {
if(items.length == 0) {
}
int i = items.length;
}
public void test2() {
final Object[] items = this.items;
if(items.length == 0) {
}
int i = items.length;
}
- 然后javap一下,javap -p -c -s Test >> Test.log,得到如下代码:
public void test();
Signature: ()V
Code:
0: aload_0 // 0 表示当前对象
1: getfield #3 // Field items:[Ljava/lang/Object;
4: arraylength
5: ifne 8
8: aload_0
9: getfield #3 // Field items:[Ljava/lang/Object;
12: arraylength
13: istore_1 // 将i结果存入局部变量表
14: return
public void test2();
Signature: ()V
Code:
0: aload_0
1: getfield #3 // Field items:[Ljava/lang/Object;
4: astore_1
5: aload_1 //load 局部变量 items
6: arraylength
7: ifne 10
10: aload_1
// 这里少了getfield,因为aload_1 load的就是items
11: arraylength
12: istore_2
13: return
-
我的理解:
1、final的数据不可变,因此更安全,防止意外修改,阅读代码时更清晰(我们知道这个东西不能修改,更易于读代码),是一种好的编程习惯;
2、更快,因为你每次都直接this.items会发生如下操作(字节码表示):
8: aload_0 //0 表示当前对象
9: getfield #3; //得到当前对象的items从字节码可以看出需要两条指令;
如果 final Object[] items = this.items; 如果接下来使用的话,直接从堆栈取items的引用,更快。