本文由Arckal撰写,转载请注明出处:http://blog.csdn.net/u014108439/article/details/52966794
Java数组是一种引用数据类型。数组变量并不是数组本身,而是指向堆内存中存放的数组对象。什么是堆内存和栈内存呢,先看一下堆和栈的区别:
栈
- 用于存储局部变量,数据使用完(程序退出局部变量作用域后),所占内存自动释放。
堆
- 用于存储数组和对象,通过new建立的实例都存放在堆内存中。
- 每个实体都有内存地址值
- 实体中变量都有默认的初始化值
- 实体不在被使用,会在不确定的时间被JVM垃圾回收
数组初始化
数组初始化分两种
- 静态初始化: 程序员在初始化数组时为数组每个元素赋值;
- 动态初始化: 数组初始化时,程序员只指定数组的长度,由系统为每个元素赋初值。
- 静态初始化
//方法1
int a[] = {1,2,3};
//方法2
int [] a = {1,2,3};
//方法3
int [] a = new int[]{1,2,3};
以上三种方法都是建立一个数组对象,存放三个int变量,这三种方法都是等价的。
- 动态初始化
int [] a = new int[3];
a[0] = 1;
a[1] = 2;
a[2] = 3;
第1句话初始化了一个数组变量a,由于初始化语句未赋值,所以被默认为{0,0,0}
第2到第4句为动态赋值。
数组在内存中的存储方式
如下图所示,int [] x = new int{1,2,3};
这句代码声明了一个int数组变量x
存储在栈内存中,然后在堆内存建立一个int数组,包含三个值{1,2,3},然后将对这个数组的引用赋给 x
,用System.out.println(x);
打印出来就是 [I@6d06d69c
,[
代表数组,I
代表int,@
后面十六进制数字代表堆内存中数组的内存地址。
由于数组是引用数据类型,即变量 x 在栈中存储的是堆中数组的引用。
数组变量并不是数组本身,而是指向堆内存中存放的数组对象。因此,可以改变一个数组变量所引用的数组。
int [] x = {1, 2, 3};
int [] y = x;
这里将数组x
的引用赋给数组y
,这也是初始化的一种方式。
长度为0的数组
还有一种方式:
int [] z = {};
大家看到这可能就不解了,这是什么鬼?这句话其实是建立了一个长度为0的数组,但不为null
。这种用法一般在不知道数组长度的情况下声明数组。使用时可以这样扩容z = Arrays.copyOf(z, z.length+3);
,这句代码看似将数组z的长度扩容至3,但其实这个z已不是扩容前的z了,这句代码的实质是,在堆内存中新建了一个长度为原数组长度加3的数组,重新赋给了z,下面贴出测试代码:
package array;
import java.util.Arrays;
public class ArrayTest
{
public static void main(String[] args)
{
int [] y = {};
System.out.println(y);
System.out.println(y.length);
y = Arrays.copyOf(y, y.length+3);
System.out.println(y);
System.out.println(y.length);
}
}
运行结果:
[I@15db9742
0
[I@6d06d69c
3
可以看到数组z的长度和引用地址都变了。