一. 声明,定义和分配内存
在Java中,声明和定义是同一个意思,不做区分。下面这些都是声明(定义)一个变量。
栈:存放局部变量(包括基本数据类型的变量和对象的引用)
堆:存放new的对象
声明一个变量,就在栈上开辟了一块空间,分配内存了。如果只声明,没初始化。那么栈上分配的内存中什么都没存。但是这种情况不会存在,因为Java规定,局部变量在使用前必须要初始化。
对于基本数据类型来说,之后对变量初始化和赋值,栈上分配的内存存的就是这个值。
对于引用数据类型来说,使用new创建对象后,才会在堆上分配内存来存储这个对象。栈上分配的内存中存储的是对象的地址。堆上分配的内存存的是对象(对象没初始化,会有默认值)。如果没有new对象,而是赋值null,那么就不会在堆上分配内存,栈上分配的内存中存的是null。
分配内存数组例子:
int[] array;声明了一个数组array,在栈上分配了内存,内存中什么都没有,没有在堆上分配内存
int[] array = new int[5];声明了一个数组array,在栈上分配了内存。new了一个对象,给对象在堆上分配内存了,但对象没初始化。栈上分配的内存中存的是对象的地址,堆上分配的内存中存的是默认值0。
int[] array = new int[]{1,2,3,4,5};声明了一个数组array,在栈上分配了内存。new了一个对象,给对象在堆上分配了内存,并且对象初始化了。栈上分配的内存中存的是对象的地址,堆上分配的内存中存的是{1,2,3,4,5};
int[] array = new int[0]; 和 int[] array = {};声明了一个数组array,在栈上分配了内存。new了一个空对象,在堆上分配了内存。栈上分配的内存中存的是对象的地址,堆上分配的内存中什么都没有。
int[] array = null;声明了一个数组array,在栈上分配了内存。array = null,没有new对象,所以没有在堆上分配内存。栈上分配的内存中存的就是null。
int[] array = new int[0]; 和 int[] array = {}; —— 数组长度为0,是空数组
!!!对于引用数据类型来说,我们一般说的有没有分配内存指的是堆内存,有没有初始化也指的是对象。
只要new对象了,就会在堆上分配内存。空数组(数组长度为0)也会分配。因为虽然空数组不包含任何元素,但它仍然需要一定的内存来存储对象本身的元数据信息,例如数组长度等等信息。
二. 初始化和赋值
初始化:赋初值(第一次赋值)
使用new运算符创建数组对象,在堆上分配内存了,才将array初始化为一个真正的数组。
int[] array1 = new int[5]; int[] array2 = new int[]{1,2,3};
变量array1和array2都初始化了。里面存的都是地址。
new int[5] 这个数组对象,没有初始化,里面放的是默认值。
new int[]{1,2,3} 这个数组对象,初始化了。里面放的是{1,2,3}