第一课:数组与内存控制

当数组的所有元素都被分配了合适的内存空间,并指定了初始值时,数组初始化完成。

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属性返回系统为数组所分配的连续内存空间的长度。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值