前言
可以接受过度的赞扬,那理应也可以接受过度的批评。
目录
数组的创建与初始化
引用类型
数组作为函数的参数
动态初始化:在创建数组时,直接指定数组中元素的个数
int[] array = new int[10];
静态初始化:在创建数组时不直接指定数据元素个数,而直接将具体的数据内容进行指定。
语法格式:T[] 数组名称 = {data1, data2, data3.....};
int[] array1 = new int[]{0,1,2,3,4,5,6,7,8,9};
double[] array2 = new double[]{1.0, 2.0, 3.0, 4.0, 5.0};
String[] array3 = new String[]{"hell", "Java", "!!!"};
注意事项:
静态初始化虽然没有指定数组的长度,编译器在编译时会根据{}中元素个数来确定数组的长度。
静态初始化时, {}中数据类型必须与[]前数据类型一致。
静态初始化可以简写,省去后面的new T[]。
// 注意:虽然省去了new T[], 但是编译器编译代码时还是会还原
int[] array1 = {0,1,2,3,4,5,6,7,8,9};
double[] array2 = {1.0, 2.0, 3.0, 4.0, 5.0};
String[] array3 = {"hell", "Java", "!!!"};
数组中元素的默认值:
类型 |
默认值 |
byte |
0 |
short |
0 |
int |
0 |
long |
0 |
float |
0.0f |
double |
0.0 |
char |
/u0000 |
boolean |
false |
引用类型 |
null |
基本数据类型创建的变量,称为基本变量,该变量空间中直接存放的是其所对应的值;
而引用数据类型创建的变量,一般称为对象的引用,其空间中存储的是对象所在空间的地址。
举个例子:看看如下代码在内存中是如何存放的
public static void func() {
int a = 10;
int b = 20;
int[] arr = new int[]{1,2,3};
}
从上图看一看到,引用变量并不直接存储对象本身,可以简单理解成存储的是对象在堆中空间的起始地址,通过改地址,引用变量便可以去操作对象。有点类似C语言中的指针,但是Java中引用要比指针的操作更简单。
再看一道例题:
public static void func() {
int[] array1 = new int[3];
array1[0] = 10;
array1[1] = 20;
array1[2] = 30;
int[] array2 = new int[]{1,2,3,4,5};
array2[0] = 100;
array2[1] = 200;
array1 = array2;
array1[2] = 300;
array1[3] = 400;
array2[4] = 500;
for (int i = 0; i < array2.length; i++) {
System.out.println(array2[i]);
}
}
在执行array1 = array2 这行代码后,栈与堆中的数据如下图:
array1原来指向的数组被自动释放掉了,随后就是基础的对数组的操作了,这里就不再赘述。若数组在定义是赋值null,则不指向任何对象。
在方法一文中已经提到过,形参的值是实参的一份临时拷贝。而在上文中,我们也了解到,数组名中存放的是指向对象的地址,所以,当数组名作为参数传递是,地址也会拷贝到形参中,这时,实参和形参指向的是同一个对象,通过形参也可以改变对象中的数据。
举个例子:
public static void main(String[] args) {
int[] arr = {1, 2, 3};
func(arr);
System.out.println("arr[0] = " + arr[0]);
}
public static void func(int[] a) {
a[0] = 10;
System.out.println("a[0] = " + a[0]);
}
// 执行结果
//a[0] = 10
//arr[0] = 10
总结:所谓的引用,本质上只是存了一个地址,Java将数组设定成引用类型,这样的话后续进行数组参数传参,其实只是将数组的地址传入到了方法形参中,这样可以避免整个数组的拷贝。
我是专注学习的章鱼哥~