在谈这数组与引用之前,我们先了解一下Java中的数据类型,这样更有助于我们理解。
1.简单介绍引用类型
内存是一块连续开辟的存储空间,用于存储运行时所需要的数据。在Java虚拟机中对内存划分成五个功能:程序计数器,虚拟机栈,本地方法栈,堆,方法区。
其中虚拟机栈是创建局部变量,操作数栈,返回地址等数据,我们的基本数据类型就是存储在虚拟机栈上的。
而堆存储的是 new 创建的对象,堆是随着程序开始运行时创建,随着程序退出而销毁,只要创建的对象数据还在使用,就不会销毁。我们的引用数据类型就存储在堆上,而Java里面的数组就是引用数据类型。
简单来说这两者之间的区别就是,基本数据类型在内存中直接存储其对应的值,而引用数据类型在内存空间中存储的是对象的空间地址。
2.利用画图的形式来理解引用数据类型
假设我们定义了四个变量a,b,c,d
public static void main(String[] args) {
int a =10;
double b = 10.00;
float c = 10;
short d = 1;
}
我们用画图的形式展现出他们的存储方式是这样的:
基本数据类型在栈上面开辟了一块空间并且直接在这块空间里面存储他们对应的值
而对于引用数据类型在栈上面同样也是开辟了一块空间,但是存储的是堆上对象的地址,通过引用对象的地址,就可以找到所相对应存储的值,我们利用画图的形式来理解
在这里我们创建了一个数组,它在内存中的栈开辟了一块空间但是这个变量存储的是堆上所对应的地址,堆上开辟的空间存储的才是数组里面的内容
利用代码我们也可以很好的解释这一点:如果我们直接打印数组的变量名那么得到就会是一串地址,变量引用这串地址就可以找到他在堆上所存储的数据。
public static void main(String[] args) {
int[] array = {1,2,3,4,5};
System.out.println(array);
}
运行结果如下:
如果我们用字符串的形式打印数组的话我们就可以充分的证明:变量引用这串地址就可以找到他在堆上所存储的数据。
public static void main(String[] args) {
int[] array = {1,2,3,4,5};
System.out.println(Arrays.toString(array));
}
}
运行结果如下:
3.数组传参
public static void fun1(int[] array) {
array[0]=99;
System.out.println(Array.toString(array));
}
public static void fun2(int[] array) {
array = new int[10];
System.out.println(Array.toString(array));
}
public static void main3(String[] args) {
int[] array = {1,2,3,4,5};
fun1(array);
fun2(array);
}
假设我们创建了两个新的方法,那么请问在主函数中调用这两个方法的结果会是怎样的?
答案是
在方法 fun1 中我们将引用地址传进方法中,在方法中改变了引用中的内容,将下标 0 的数据改成99,最后我们打印出来的结果也正是这样。
而在方法 fun2 中我们传进方法里的是一个引用地址,但是我们在方法中利用new重新开辟了一块新的空间,并且我们利用方法里面的array指向我们用new开辟的新空间地址,导致我们打印出来的是 [0,0,0,0,0,0,0,0,0,0] 。
但是这并没有对我们原来的引用造成任何的影响,我们实参的引用地址并没有改变,我们堆上的内容也没有任何改变,所以最后如果我们要去打印出来原来的array上的内容还是不变的。
通过这两个例子我们可以知道了:
1.数组传参传的是引用地址
2.利用传参我们可以改变数组的内容
3.如果在方法里面使用 new 就是开辟一块新的空间并利用形参的变量名来接受这一块新的地址
以上就是本人对引用和数组的理解,如果错误还请各位指正!谢谢!