文章目录
一、初识数组
在学习变量的时候,我们知道如何定义一个变量;现在有一个要求,需要定义100个整型变量,以我们现在所学的知识,我们只能逐个定义,但这无疑是个耗时耗力的方法,为了解决类似的问题,我们引入数组的概念。
数组是 相同数据类型元素的集合,在内存中是一段连续的存储空间。
对于数组我们需要了解:
1.数组中存放的元素应为同种数据类型。
2.数组的存放空间是连续的。
3.每个存放空间都有自己的编号,即数组下标,起始位置编号为0。
二、数组的创建与初始化
1.数组的创建
语法格式:
T[] 数组名 = new T[N];
T:表示数组中存放元素的数据类型
T[]:表示数组的类型
N:表示数组的长度
如:
//创建一个数组,可以容纳10个int类型的元素
int[] array = new int[10];
2.数组的初始化
数组的初始化可以分为静态初始化和动态初始化。
2.1 动态初始化
在创建数组时,直接指定数组中元素的个数:
int[] array = new int[10];
2.2 静态初始化
在创建数组时不直接指定数组中元素个数,而直接指定具体的元素内容:
语法格式:
T[] 数组名 = new int[]{元素1,元素2,…};
如:
int[] array1 = new int[]{1,2,3,4,5};
注意事项:
1.静态初始化时虽然没有指定数组长度,但是编译器会根据{}中的元素个数来确定。
2.静态初始化时,{}中的数据类型必须与[]前的数据类型保持一致。
3.静态初始化可以简写,省掉new T[]。如:int[] array2 = {1,2,3,4,5};
静态初始化和动态初始化均可以分为两条语句书写,但当静态初始化分为两条语句时,不可简写:
//动态初始化
int[] array;
array = new int[10];
//静态初始化
int[] array1;
array1 = new int[]{1,2,3,4,5};
//静态初始化错误写法 ×
int[] array2;
array2 = {1,2,3,4,5};
如果没有对数组进行初始化,则数组中的元素存在默认值:
当元素为基本数据类型时,默认值为:

当元素为引用类型时,默认值为null。
三、数组的使用
1.访问数组中的元素
数组在内存中是存放在一段连续的空间中,这段空间的编号从0开始依次递增,此编号称为下标,数组可以通过下标访问数组中任意位置的元素:
int[] array = new int[]{1,2,3,4,5};
System.out.println(array[0]); //1
System.out.println(array[1]); //2
System.out.println(array[2]); //3
System.out.println(array[3]); //4
System.out.println(array[4]); //5
//可以通过下标对数组中的元素进行修改
array[0] = 100;
System.out.println(array[0]); //100
注意:
1.因为数组是一段连续的存储空间,所以支持随机访问,即通过下标快速访问数组中任意位置的元素。
2.下标从0开始,到N - 1结束(N为元素个数),在使用下标时,需注意不能越界,否则会导致程序报错:int[] array = new int[]{1,2,3,4,5}; System.out.println(array[5]);运行结果为:
2.遍历数组
遍历是指将数组中的所有元素都访问一遍,我们可以使用下标来逐个访问,如:
int[] array = new int[]{1,2,3,4,5};
System.out.println(array[0]); //1
System.out.println(array[1]); //2
System.out.println(array[2]); //3
System.out.println(array[3]); //4
System.out.println(array[4]); //5
但当数组中元素个数较多时,这种办法就不太适合了,我们可以使用循环来完成此操作:
int[] array = new int[]{1,2,3,4,5};
for (int i = 0; i < 5; i++) {
System.out.println(array[i]);
}
当数组中元素个数较少,我们可以使用肉眼观察,但当元素个数较多时,我们该怎么办呢?
在数组中,可以通过 数组名.length 获取数组长度。 我们将上面的代码以这种形式改写:
int[] array = new int[]{1,2,3,4,5};
for (int i = 0; i < array.length; i++) {
System.out.println(array[i]);
}
Java也给我们提供了一种更简单的循环方式:for-each 用来遍历数组:
int[] array = new int[]{1,2,3,4,5};
for (int i:array) {
System.out.println(i);
}
使用 for-i 循环和 for-each 循环最主要的区别在于能否通过下标进行操作。
四、数组是引用类型
int[] array = new int[]{1,2,3,4,5};
System.out.println(array); //[I@1b6d3586
对于上面这段代码,我们可以将其运行结果的值理解为在内存上的"地址",引用变量就是用来存储"地址"的变量。
五、Java虚拟机(JVM)的内存分布
内存是一段连续的存储空间,主要用来存储程序运行时的数据。
JVM按照不同的功能对使用的内存进行了分类:

在本章节中,我们主要使用虚拟机栈和堆:
虚拟机栈: 与方法调用相关的一些信息,每个方法在执行时,都会先创建一个栈帧,栈帧中包含有:局部变量表、操作数栈、动态链接、返回地址以及其他的一些信息,保存的都是与方法执行时相关的一些信息。比如:局部变量。当方法运行结束后,栈帧就被销毁了,即栈帧中保存的数据也被销毁了。
堆: JVM所管理的最大内存区域。使用 new 创建的对象都是在堆上保存(例如前面的 new int[]{1,2,3,4,5} ),堆是随着程序开始运行时而创建,随着程序的退出而销毁,堆中的数据只要还有在使用,就不会被销毁。
六、基本类型变量和引用类型变量
基本数据类型创建的变量,称为基本变量,变量空间中存放的是其所对应的值;而引用数据类型创建的变量,称为对象的引用,在其空间中存放的是对象所在空间的地址。
public static void main(String[] args) {
int[] array = new int[]{1,2,3,4,5};
}

通过上图分析可知,引用变量并不是直接存储对象本身,而是存储对象在堆中的起始地址,通过地址即可对对象进行操作。
理解了上面这些,我们再来看一个例子:
public static void main(String[] args) {
int[] array = new int[]{1,2,3,4,5};
int[] array1 = array;
}

通过上面这个例子,我们引申出一些知识点:
1.当方法执行完毕时,方法内的局部变量会被回收。
2.当对象没有人引用(指向)时,也会被自动回收。
3.对象一定是在堆上的,但引用变量不一定在栈上。
4.当两个引用同时指向一个对象时,不管通过哪个引用,都可以修改数组对象的值。
七、空引用
在Java中,null表示空引用,意为不指向任何对象的引用,表示一个无效的内存位置。因此,不能对这块内存进行任何读写操作,这会导致程序抛出异常:
int[] array = null; //array不指向任何对象
System.out.println(array[0]);
运行结果为:

八、数组的使用
1.作为函数的参数
我们来分析一段代码:
public static void func1(int[] array){
array = new int[10];
}
public static void func2(int[] array){
array[0] = 99;
}
public static void main(String[] args) {
int[] array = {1,2,3,4};
func1(array);
for (int i = 0; i < array.length ; i++) {
System.out.print(array[i] + " ");
}
System.out.println();
int[] array1 = {1,2,3,4};
func2(array1);
for (int i = 0; i < array1.length; i++) {
System.out.print(array1[i] + " ");
}
}


引用本质上就是存储的地址。 在上面的这段代码中,func1和func2都是将引用作为参数进行传递,func1改变了指向,所以没有对原数组产生影响,func2通过下标改变了对象的值,所以原数组也发生改变。
2.作为函数的返回值
在Java中,数组可以作为返回值返回一组数据:
public static int[] func(){
int[] array = {1,2,3,4,5};
return array;
}
public static void main(String[] args) {
int[] ret = func();
for (int i = 0; i < ret.length; i++) {
System.out.print(ret[i] + " ");
}
}
未完待续…

897

被折叠的 条评论
为什么被折叠?



