今天阅读ArrayList的迭代器实现Itr的next方法的时候,突然发现一个平时开发的时候没有注意,没有用过的方式。
Java赋值语句,居然有返回值,而且还并不是想象中的布尔类型!
public E next() {
checkForComodification();
int i = cursor;
if (i >= size)
throw new NoSuchElementException();
Object[] elementData = ArrayList.this.elementData;
if (i >= elementData.length)
throw new ConcurrentModificationException();
cursor = i + 1;
return (E) elementData[lastRet = i];
}
根据next方法的理解,显然lastRest=i 返回值应该是赋值符号右侧的值即i的值。
那么我们写一个测试类
public class Test{
public static void main(String[] args){
int index=0;
System.out.println(index =2);
System.out.println(index);
}
}
运行后发现输出结果为 2和2, 从而印证了我们的想法。
那么为什么呢?
我们尝试通过自带的反汇编命令javap -c -l Test 查看并分析反汇编后的代码:
public class Test {
public Test();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
LineNumberTable:
line 1: 0
LocalVariableTable:
Start Length Slot Name Signature
0 5 0 this LTest;
public static void main(java.lang.String[]);
Code:
0: iconst_0 // 将int类型常量0压入栈
1: istore_1 // 弹出栈顶元素0并存入局部变量1(index)
2: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
5: iconst_2 // 将int类型常量2压入栈
6: dup // 复制栈顶部一个字长内容
7: istore_1 // 将int类型的值(复制出的一个字长内容,即常量2)赋值给局部变量1 (index)
// 调用打印方法打印index
8: invokevirtual #3 // Method java/io/PrintStream.println:(I)V
11: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
14: iload_1 // 将局部变量1(index)的值(此时为2)压入栈
// 调用打印方法打印index
15: invokevirtual #3 // Method java/io/PrintStream.println:(I)V
18: return
LineNumberTable:
line 4: 0
line 5: 2
line 7: 11
line 9: 18
LocalVariableTable:
Start Length Slot Name Signature
0 19 0 args [Ljava/lang/String;
2 17 1 index I
}
我们注意到局部变量表(LocalVariableTable)里的index变量的签名为I,而反汇编出的代码中,第8行和第15行调用同一个函数,打印的值为I 即index。
因此“返回值”就是左侧引用的值,即右侧的结果,。
对反编译的指令不是足够熟悉,如果错误,欢迎指正。