数组是一种引用类型,数组引用变量只是一个引用,数组元素和数组变量在内存中时分开存放的,下面我们看一下基本类型的数组和引用类型的数组在内存中的地址分布情况
我们先来看一段代码:
public static void main(String[] args) {
int[] arr;
arr=new int[5];
for(int i=0;i<arr.length;i++) {
arr[i]=i+10;
}
}
1、int[] arr,仅定义了一个数组变量,此时内存情况如下图:
2、arr=new int[5],这段代码执行完成后,系统会在堆内存中为该数组分配一块内存空间,并初始化值0,如下图所示:
3、接着通过for循环遍历数组依次为数组赋值(注意:这里用for循环为数组赋值不能使用foreach遍历赋值,因为foreach(foreach语法:for (int i : arr){ })遍历时只是拷贝了数组的副本,然后将这个副本输出,所以通过foreach遍历并不会真正改变数组的值。)内存如下图:
首先定义一个Person(所有的类都是引用类型):
public class Person {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
测试代码:
public class TestArr {
public static void main(String[] args) {
Person[] student;
student=new Person[2];
Person zhang=new Person();
zhang.setName("张三");
zhang.setAge(19);
Person li=new Person();
li.setName("李四");
li.setAge(18);
student[0]=zhang;
student[1]=li;
System.out.println("Name"+student[0].getName()+"age"+student[0].getAge());
student[0].setName("哪吒");
System.out.println(zhang.getName());
}
}
1、Person[] student,定义了一个Person类型的引用变量,此时这个变量并未指向任何有效的内存区域,此时内存如下图:
2、student=new Person[2],数组初始化,系统在堆内存中为数组分配一块内存空间,两个引用类型,值为Null,如下图:
3、声明两个Person变量,zhang和li,此时在栈内存中分配两块内存用于存储变量zhang和li,在堆内存中分配两块内存用于存储zhang和li的数据,如下图:
4、接着讲zhang赋给数组的第一个元素,li赋给数组的第二个元素,此时数组的两个元素将指向有效区域,如下图: