目录
-
-
- 1、代码
- 2、method1()解释
- 3、method2()解释
- 4、method3()解释
- 5、method4()解释
- 6、总结
-
1、代码
public class Test {
public void method1() {
int i = 10;
i++;
}
public void method2() {
int i = 10;
++i;
}
public void method3() {
int i = 10;
int a = i++;
int j = 10;
int b = ++j;
}
public void method4() {
int i = 10;
i = i++;
}
}
2、method1()解释
由于该方法不是静态方法,所以在方法被调用之前局部变量表中下标为0的位置已经有一个
this
了,然后来看字节码,
bipush 10
表示需要往操作数栈中添加数值10,
istore_1
表示数值10需要从操作数栈中弹出来,然后添加到局部变量表中下标为1的位置,
iinc
是自增操作,后面第一个
1
代表对局部变量表中下标为1上的数值进行自增,也就是那个10,
by 1
表示自增
1
就可以了,那局部变量表中下标为
1
的数值就变成了
11
3、method2()解释
可以看出,字节码和上面的一样,说明单独使用
++i
和
i++
是没有区别的,还记得
for(int i = 0; i < 10; i++){***}
这种操作吗,其实把里面的
i++
换成
++i
也是没有问题的
4、method3()解释
由于该方法不是静态方法,所以在方法被调用之前局部变量表中下标为0的位置已经有一个
this
了,然后来看字节码,
bipush 10
表示需要往操作数栈中添加数值10,
istore_1
表示数值
10
需要从操作数栈中弹出来,然后添加到局部变量表中下标为
1
的位置,
iload_1
表示将局部变量表中下标为1上的值取出来压入操作数栈中,该值正是10,
iinc 1 by 1
的含义在
method1()解释
中已经说过了,执行之后的结果是局部变量表中下标为
1
的位置上的
i
变成了
11
,这里不再赘述,
istore_2
表示将操作数栈中的数值
10
弹出栈,然后放入局部变量表中下标为
2
的位置,这也就是变量
a
所在的位置
之后是
bipush 10
代表将数值
10
压入操作数栈,
istore_3
代表将
10
弹出操作数栈,然后放入局部变量表中下标为
3
的位置,
iinc 3 by 1
代表将局部变量表中下标为
3
位置上的数,
10
自增
1
,那么该局部变量表中下标为
3
位置上的值就变成了
11
,
iload_3
代表将局部变量表中下标为
3
的数值
11
取出来压入操作数栈中,
istore_4
代表将数值
11
弹出栈,然后放入到局部变量表中下标为
4
的位置,这也就是变量
b
所在的位置
5、method4()解释
虽然字节码不多,但是这个是最有意思的,由于该方法不是静态方法,所以在方法被调用之前局部变量表中下标为0的位置已经有一个
this
了,然后来看字节码,
bipush 10
表示需要往操作数栈中添加数值10,
istore_1
表示数值
10
需要从操作数栈中弹出来,然后添加到局部变量表中下标为
1
的位置,
iload_1
表示将局部变量表中下标为1上的值取出来压入操作数栈中,该值正是
10
,
iinc 1 by 1
的含义在
method1()解释
中已经说过了,执行之后的结果是局部变量表中下标为
1
的位置上的
i
变成了
11
,这里不再赘述,
istore_1
表示将操作数栈中的数值
10
弹出栈,然后放入局部变量表中下标为
1
的位置,这也就是变量
i
所在的位置,所以最终
i
变成了
10
,确实很有意思,很神奇
6、总结
一般遇到这种问题,可以简单来思考就行了
i++:
++放在后面
,那就
先赋值,再++
++i:
++放在前面
,那就
先++,再赋值
不过需要小心
method4()
方法中的
i = i++
这种的