当数组的所有元素都被分配了合适的内存空间,并指定了初始值时,数组初始化完成。
1.1数组初始化
数组:复合结构,多个类型相同的变量的组合。
Java中的数组变量是引用类型的变量。
1.1.1java数组是静态的
静态:当数组被初始化之后,该数组的长度是不可变的。
Java中的数组必须经初始化之后才能使用。
初始化:为数组对象的元素分配内存空间,并为每个数组元素指定初始值。
初始化的两种方式:
①静态初始化:
int[] arr=new int[]{2,3,4,4};
也就是程序员显式指定每个元素的初始值,由系统决定数组长度。
②动态初始化:
int[] arr=new int[4];
也就是程序员只是指定了数组长度,由系统为数组元素分配初始值。
但是,无论是哪种情况,一旦初始化完成,数组长度就不可改变了。
◆突然想到一种情况,如果是定义字符串数组的话,采用的是动态初始化,那么初始化的值由系统决定,又字符串是不可变的类。因此,这种情况,数组中的元素全都为””.
让我来做个试验:
public class temtest {
public static void main(String[] args) {
String[] strs=new String[3];
for(int i=0;i<3;i++) {
strs[i]="fl";
}
for(String s:strs){
System.out.println(s);
}
}
}
结果是:
fl
fl
fl
因此,我的想法是错误的,那我继续看下去,系统究竟是怎么初始化的呢?
系统初始化:
byte,short,int,long->0;
float,double->0.0;
char->’\u0000’;
boolean->false;
引用类型:null。
不要同时使用静态初始化和动态初始化,即又指定长度,又给出了初始值。
初始化之后,数组元素的内存空间分配就结束了,只能改变数组元素的值,而不能改变数组的长度。
◆
public class temtest {
public static void main(String[] args) {
String[] books=new String[] {"疯狂java讲义","轻量级javaee企业应用实战","疯狂AJAX讲义","疯狂XML讲义"};
for(String s:books) {System.out.print(s+" ");}
for(int i=0;i<4;i++) {
books[i]="fl";
}
for(String s:books) {System.out.print(s+" ");}
}
}
结果:
疯狂java讲义 轻量级javaee企业应用实战 疯狂AJAX讲义 疯狂XML讲义 fl fl fl fl
其实我忽略了一点,数组本身就是一个引用类型,数组books存在于栈内存中,指向内容存在堆内存中,所以不是String类元素的值改变了,而是数组的指向变了,由指向"疯狂java讲义","轻量级javaee企业应用实战","疯狂AJAX讲义","疯狂XML讲义"的堆内存,变为指向"fl" "fl" "fl" "fl"的堆内存。
java的数组变量是一种引用类型的变量,数组变量并不是数组本身,它只是指向堆内存中的数组对象。
如果两个数组,指向了同一个内存空间,那么当一个数组的某个元素值改变的话,那同时也会改变另外一个数组的元素值。
无论怎样,怎么改变,改变指向,改变元素,都改变不了数组指向的长度。
◆
public class temtest {
public static void main(String[] args) {
String[] books=new String[] {"疯狂java讲义","轻量级javaee企业应用实战","疯狂AJAX讲义","疯狂XML讲义"};
String[] haha=new String[] {"fox","fox","rz"};
books=haha;
for(String s:books) {System.out.print(s+" ");}
System.out.println(books.length);
String[] hiahia=new String[] {"fox","fox","rz","rz"};
books=hiahia;
for(String s:books) {System.out.print(s+" ");}
System.out.println(books.length);
String[] keke=new String[] {"fox","fox","rz","rz","rz"};
books=keke;
for(String s:books) {System.out.print(s+" ");}
System.out.println(books.length);
}
}
结果:
fox fox rz 3
fox fox rz rz 4
fox fox rz rz rz 5
这样看来好像是改变了数组的长度,但是呢,这个长度其实是指指向空间的长度,而不是数组本身,我们定义是数组只是一个引用变量。我们无法改变指向对象的长度。
没有被引用的变量静等垃圾回收。
因此,要好好理解数组是引用变量这一概念。
1.1.2数组一定要初始化吗?
始终记住:java的数组变量是引用类型的变量,它并不是数组对象本身,只要让数组变量指向有效的数组对象,程序中即可使用该数组变量。
数组:引用变量,存在栈内存中;指向对象,对象存于堆内存中。
因此,作者说,如果理解好了数组在内存中的分配机制,其实不用对数组进行初始化?为什么呢?因此需要初始化的一直都是被引用的对象,而不是数组本身。
1.1.3基本类型数组的初始化
数组元素用起来就像是普通变量。
所有局部变量都是放在栈内保存的,不管其实基本类型的变量还是引用类型的变量,都是存储在各自的方法栈区中;但引用类型变量所引用的对象(包括数组、普通java对象)总是存储在堆内存中。
堆内存中的对象不允许直接访问,只能通过引用变量。
引用变量实质上是一个指针,只要程序通过引用变量访问属性,或者通过引用变量来调用方法,该引用变量将会由它所引用的对象代替。数组需要有所指向,才能访问属性,不然访问属性也不知道访问什么。
1.1.4引用类型数组的初始化
引用类型数组:数组元素仍然是引用类型的。也就是数组中存在的元素指向另外一块内存。
1.2使用数组
1.2.1数组元素就是变量
◆可能看到这大家会觉得有点混乱,举个例子:
for(String s:array){System.out.println(s);},前文中我有用到这个语句,其实数组中的元素呢,就好比这个语句里面的s,这是一个变量,变量引用对象的值,如此而已。因此,对象改变,会影响变量;但是变量改变呢,对其所引用的对象没影响。
1.2.2没有多维数组
N维数组实际上就是:数组元素是(N-1)维的数组。
Java允许将多维数组当成一维数组处理。初始化多维数组时可以先只初始化最左边的维数,此时该数组的每个元素都相当于一个数组引用变量,这些数组的元素还需要进一步初始化。
数组的length属性返回系统为数组所分配的连续内存空间的长度。