由Java内存机制引发的一些语法问题

i = i++

1
2
3
int i = 0;
i = i++;
System.out.println("i的值是 "+i);

根据我们通常所知道的后自增先使用后增加的道理,i++在使用后i自身会增加一个数值,初始值为0时,自增后就是1,那么输出的结果应该是1.但实际上这题的结果却是0。

1
i的值是 0

这是因为jvm在处理i = i++时, 会建立一个临时变量来接收i++的的值,然后返回这个临时变量的值,返回的值再被等号左边的变量接收了,这样就是说i虽然自增了但是又被赋值了0,这样输出的结果自然就是0了。

不妨我们用temp临时变量来接收i++的值,来看一下结果。

1
2
3
4
5
public static void main(String[] args) {
int i = 0;
int temp = i++;
System.out.println("temp的值是 "+temp);
}
1
temp的值是 0

可以看到temp的结果就是0,也就是说赋值号右边传递过来的是i未自增前的值,这符合后自增运算符先使用后增加的原则,这时候我们再输出一下i的值。

1
2
3
4
5
6
public static void main(String[] args) {
int i = 0;
int temp = i++;
System.out.println("temp的值是 "+temp);
System.out.println("i的值是 "+i);
}
1
2
temp的值是 0
i的值是 1

i也的确自增了一个值,这样就好理解为什么i = i++中输出第一个i为什么是0了,因为i在自增后又被等式右边的值覆盖了。也就是说这里的i的值发生了三次变化,第一次是我们定义i = 0;第二次就是i自增后变成了1;第三次就是i又被0值覆盖了。

str= “test ok”

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class Example { 
String str = new String("good");
char[] ch = {'a','b','c'};
public static void main(String[] args) {
Example ex = new Example();
ex.change(ex.str, ex.ch);
System.out.print(ex.str +"and");
System.out.print(ex.ch);
}

public void change(String str, char ch[]){
str= "test ok";
ch[0]= 'g';
}
}

结果:

1
goodandgbc

在change方法中,str被指向了”test ok”,这个方法参数只是原来的全局变量str的一个副本,而原来的str仍然指向“good”。而ch数组被直接修改了堆内存中的值。

参考链接

  1. 人生第一步:java中 i = i++ 的结果
  2. 牛客网:题目

土豪将鼓励我继续创作和搬运!