黑马程序员--02.Java语言基础--03.【数组】

来源:互联网 发布:aspen plus软件 编辑:程序博客网 时间:2024/05/01 17:54

Java语言基础--02.基本组成元素

                                                  数组

----------- android培训、java培训、java学习型技术博客、期待与您交流! ------------

1.    数组的相关基本概念

1). 数组的概念

(1).定义

       同一种类型数据的集合。数组是一种容器。

(2). 容器的概念

能存储数据的地方就是容器

(3). 数组的优势

能够自动为数组中的元素自动从0开始进行编号,方便对元素的操作。

(4). 关键字new的作用

       [1]. 用来在内存产生实体

       [2].实体:包括类的对象数组(数组类对象可以通称为new建立的实体)

(5). 数组的数据类型

数组是Java中一种独立的数据类型

Java中三种引用类数据类型:class、interface和[]数组类型。

2). Java的内存结构

(1). Java的五大内存区域

[1].内存、内存、方法区、本地方法区和寄存器

       个人觉得分成了方法区本地方法区是因为:方法区本身是Java语言编写的方法,而本地方法区是Java调用底层操作系统的方法。两者有本质的区别,所以分成了两片内存区域

[2]. 内存的特点

       {1}.存放的内容:用于存储定义在方法中局部代码块局部变量

       {2}.栈内存的管理:所占用的空间直到相对应的代码块或者方法执行完就立即自动释放

[3]. 内存的特点****(助记:存储内容内存地址值默认初始化值垃圾回收机制(GC机制))

       {1}.存储的内容:通过new建立的实体全部存放到堆内存中

       {2}.每一个实体都有自己的内存地址值

       {3}.实体中的变量都有默认的初始化值

       {4}. 当实体不再被使用的时候,会在不确定的时候,有垃圾回收器 (GC)回收(释放空间)

(2). 数组的初始化过程****

       举例说明:int[] arr =newint[3]; //体现堆内存4个特点

【step 1】在中为数组类型的变量arr开辟空间

【step 2】赋值运算右边是new运算。new得到的数组实体内存中开辟空间

【step 3】系统为堆内存中的数组对象分配地址(地址值)。假设为0x0079

【step 4】系统自动为数组中的元素进行初始化(默认值)。这里是int, 值全部为0

【step 5】此时将数组实体的首地址赋值给左边栈内存中的arr变量。arr值为0x0079

【step 6】赋值完成后,x就指向了这个数组实体也叫x引用了这个数组实体


(3). Java中的垃圾以及垃圾回收机制 (GC机制)

[1]. Java中的对象何时变成垃圾

当一个堆内存中的对象在没有引用指向它的时候,这个对象就被JVM视为垃圾

[2]. 垃圾不会被立刻清理掉,而是在未知的时间点,JVM启动GC来回收这个对象所占用的空间。

[3]. Java中的垃圾回收机制(和C++相比)

Java中不用手动清除堆内存对象,只要将堆内存中的对象变成垃圾,这个垃圾对象就会被GC在某个不确定的时间自动清除掉。

(4). 堆内存对象Prac

int[] x =newint[3];int[] y =x;y[1] =89;x =null;


请问这段程序执行完之后,在堆内存中有没有垃圾对象?

分析:由于x变成null之前,已经把数组的首地址的值传给了y,所以x变成null之后,y还是指向了内存中的数组对象,所以程序执行完之后,对内存中的数组对象在栈内存中仍然有引用变量指向它,所以堆内存中没有垃圾对象。

如图:

 

3). 数组初始化以及常见的问题

(1). 数组初始化的方式及其注意事项

       [1].通过显式new进行初始化

       {1}.不明确数据:int[] arr =new int[整数]; <===> int arr[] =new int[整数];

       {2}.明确数据:int[] arr =new int[]{1,2,3,4,5,6}

一定注意!!明确数据之后,new中的[]千万别写整数!!!

       [2].显式new的简化形式

              明确数据:int[] arr ={1,2,3,4,5,6}; //仅仅就是{}来初始化就可以了!!!

(2). 数组越界为什么编译器不进行检查呢?

****原因:因为new之后在堆内存中开辟空间,并划分出多少小的数组元素单元这个动作是在程序运行的时候才进行的,属于编译的范围之内!!!!

编译要进行的就仅仅是:语法检查!!

举例说明:

int[] x =new int[3];

//javac要做的:合乎数组定义的语法么?检查两边赋值的类型一样么?一样 OK

至于new要在内存中开辟空间,不是javac的职责范围之内,所以javac并不关心这个里面的数字到底是多少!编译只是关心使用的时候,符合语法的模子就行。不符合,就出错!!

System.out.println(x[3]);

由于javac不知道数组在内存中会被开辟几个空间,所以访问x中的第几个元素并不关心。只要是满足引用数组元素的语法:数组名[下标值] 这个模子即可。

***************************

但是 运行时候,new会在堆内存中开辟空间,可访问的数组元素名是:x[0], x[1]和x[2]。但是在运行打印x[3]的时候,JVM找不到这个元素 抛出数组越界异常。    

(3). 通过程序打印数组的类型

----------- android培训、java培训、java学习型技术博客、期待与您交流! ------------