基本数据类型与引用数据类型在内存结构上的区别
经过上一节的学习,咱们对数组有了大致的了解,包括如何定义使用,不清楚的小伙伴戳这里哈,非常详尽!!!
一/ 引入
【案例一】看一下下面的输出结果是多少。
public class TestArray2{
public static void main(String[] args){
int a=10;
int b=a;
b=100;
System.out.println(a);
}
}
AI 代码解读
毫无疑问,答案是10。
看一下运行结果吧:
【案例二】看一下下面的输出结果是多少。
public class TestArray2{
public static void main(String[] args){
int[] x={10,20,30};
int[] y=x;
y[0]=100;
System.out.println(x[0]);
}
}
AI 代码解读
看一下结果:
这个结果,很多人就会有疑惑了(疑惑是10,还是100)。
数组之所以难,不是在它的使用。而是它底层的原理,你到底有没有弄明白。
别着急,往后看,你会越来越通透。
二/ 内存存储
【案例一】
public class TestArray2{
public static void main(String[] args){
int a=10;
int b=a;
b=100;
System.out.println(a);
}
}
AI 代码解读
上面的案例一,内存上是如何执行的?
为了方便理解,画图解释,如下:
【案例二】
public class TestArray2{
public static void main(String[] args){
int[] x={10,20,30};
int[] y=x;
y[0]=100;
System.out.println(x[0]);
}
}
AI 代码解读
上面的案例二,内存上又是如何执行的?
之前我们说过变量,变量在内存中:
1.是栈内存中的小容器,类型定义了只能存储这种东西。
2.容器中只能存一份。
①int[] x={10,20,30};
现在可以看到,x是一个数组,三个数是不能像变量那样存入一个空间的。
先来看一下int[] x={10,20,30};
的标准写法:int[] x=new int[]{10,20,30};
。
new
是新建的意思。
:star:==以后只要见到new
关键字,相当于在堆内存空间中申请开辟了一块新的空间。==
既然新建了一块空间,那这块空间长啥样呢?
就是new
关键字后面的内容,即开辟一块int[]
数组类型的空间。
那数组类型的空间又长啥样?
:star:==数组在堆内存中的空间形态,是一串连续的地址。==
每一个小格子存的是int
类型的数据。
整个开辟空间并存完东西的过程,叫做 数组的初始化。
如下图:
:question: 既然创建完成了,那么如何把10,20,30存入x空间里面呢?
既然在堆内存中是一串连续的地址。
那么,就把第一个地址交给x处理。
:star: ==x
里面存的其实是地址
(门牌号)。==
我们可以通过x
里面存放的地址,找到数据在堆内存里面存储的位置。
第一个位置找到了,后面的是连续的,就都找到了。
现在暂时理解为是地址,其实是一个HashCode,以后再说这个。
如下图:
② int[] y=x;
第二步,继续创建一个y空间,名字叫y,存储类型为int[]
数组类型。
y空间
的值是x
给的。
x
里面存的是一个地址
。
那么就是,==x
将自己空间的地址
,复制了一份,交给了y
。==
如下图:
既然y
里面存的是地址,那么就可以通过这个地址访问到堆内存中的数据。
③y[0]=100;
再来看最后一步,这行代码的含义就是:
通过y
里面存储的地址,找到堆内存中的数据(即10所在的位置)。
然后在常量区内复制了一份100,交给了堆内存中第一个位置。(将第一个数据,改成了100)
这里是y[0]
,就是第一个位置,即10。所以覆盖的就是10啦。
如下图:
④ System.out.println(x[0]);
虽然输出的是x[0]
,但是x
里面的地址指向的堆内存的数据,发生了变化。
第一个数据已经变成了100,所以最后输出,就是100啦。
:red_car:为了方便大家理解,在这里再举个小例子。可以对照着看我上面画的图哈。
小王(x)和小明(y)两个人,都有同一个仓库的钥匙(地址)。
现在小明(y)将仓库里面的西瓜拿走了,装入了菠萝。
过一会,小王(x)再次打开仓库,里面存放的就是菠萝啦。
三/ 总结
(1)基本类型变量空间存储的是值
,传递的是值
,如【案例一】。
一个改变,另一个不变。
(2)引用类型变量空间存储的是地址
(引用),传递的是地址
(引用),指向同一个空间。
空间内数据改动了,那就都会改动,如【案例二】。
一个改变,另一个跟着改变。
(3)所有的变量空间都存储在栈内存
里。(简单来说,等号左边的东西在栈内存里面)
变量空间可以存储基本数据类型,也可以存储引用数据类型。
如果变量空间存储的是基本数据类型
,存储的是值
,一个变量改变,另一个不会跟着改变。
(每一个变量里面存储的是一个固定的值,别人变化和我无关)。
如果变量空间存储的是引用数据类型
,存储的是地址
(引用),一个变量地址对应的值改变,另一个跟着改变。