第一课:数组与内存控制

xiaoxiao2021-02-28  30

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

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

转载请注明原文地址: https://www.6miu.com/read-2630089.html

最新回复(0)