数组及其内存管理——数组初始化
来源:互联网 发布:轩辕传奇神器数据图 编辑:程序博客网 时间:2024/06/05 18:10
1、 数组初始化
如果程序需要多个类型相同的变量时,就可以考虑定义一个数组。Java语言的数组变量时引用类型的变量,因此具有Java引用变量的特性。
1、1 Java数组静态特性
Java语言是典型的静态语言,因此Java数组是静态的,即当数组被初始化之后,其所占的内存空间、数组长度均是不可变的。Java程序中的数组必须经过初始化后才能够使用,所谓初始化,即创建实际的数组对象,也就是在内存中为数组对象分配空间,并未每个数组元素指定初始值。
数组的初始化有以下两种方式:
静态初始化:初始化时由程序员显式指定每个数组元素的初始值,由系统来决定数组长度。
静态初始化:初始化时由程序员指定数组长度,由系统为每个数组元素分配初始值。
public class ArrayTest {public static void main(String[] args) {String[] books = new String[] { //采用静态初始化方式初始数组"book1","book2","book3"};String[] strArr = new String[5]; ////采用动态初始化方式初始数组System.out.println("第一个数组的长度:" + books.length);System.out.println("第二个数组的长度:" + strArr.length);}}
输出结果为:
第一个数组的长度:3
第二个数组的长度:5
Java语言的数组变量时引用类型的变量,books和strArr数组在内存的分配示意图如下所示。
从上图可以知道,对于静态初始化方式,程序员无须指定数组长度,但要指定数组的元素,长度由系统来决定。对于动态初始化方式,程序员只需要指定数组的长度,即为每个数组元素指定所需的内存空间,系统将负责为这些数组元素分配初始值。
注意:不要同时使用静态初始化和动态初始化方式。也就是说,不要再进行数组初始化时,既指定数组的长度,又为每个数组元素分配初始值。
Java数组是静态的,一旦数组初始化完成,数组元素的内存空间分配即结束,程序只能改变元素的值,而无法改变数组长度。需要指出的是,Java的数组变量是一种引用的变量,数组元素并不是数组本身,它只是指向堆内存中的数组对象。因此,可以改变一个数组变量所引用的数组,这样可以造成数组长度可变的假象。
例如:
import java.util.Arrays;public class ArrayTest2 {public static void main(String[] args) {String[] books = new String[] { //采用静态初始化方式初始数组"book1","book2","book3"};String[] strArr = new String[5]; ////采用动态初始化方式初始数组strArr = books;System.out.println("第一个数组的长度:" + books.length);System.out.println("第二个数组的长度:" + strArr.length);System.out.println("srtArr:" + Arrays.toString(strArr));}}
输出结果为:
第一个数组的长度:3
第二个数组的长度:3
srtArr:[book1, book2, book3]
上面代码中将strArr数组变量指向books数组变量所引用的数组,原来strArr数组变量所引用的数组长度依然是5,但是不再有任何引用变量引用该数组,因此它将会变成垃圾,等着垃圾回收机制来回收。此时,books和strArr数组在内存的分配示意图如下所示。
1、2 关于数组的初始化
Java的数组变量只是引用类型的变量,它并不是数组对象本身,只要让数组变量指向有效的数组对象,程序中即可使用该数组对象。
import java.util.Arrays;public class ArrayTest3 {public static void main(String[] args) {int[] strArr = new int[]{1 , 2 , 3 , 4}; //定义并初始化一个数组int[] number; //定义一个数组number = strArr;System.out.println("number:" + Arrays.toString(number));number[2] = 5;System.out.println("strArr:" + Arrays.toString(strArr));}}
输出结果为:
number:[1, 2, 3, 4]
strArr:[1, 2, 5, 4]
程序定义了number数组变量之后,并没有立刻进行初始化过程。当程序执行number = strArr;之后,number变量指向strArr变量所引用的数组,此时两个变量都引用同一个数组对象,strArr和number数组在内存的分配示意图如下所示。
注意:对数组执行初始化,其实并不是对数组变量执行初始化,而是在堆内存中创建数组对象,也就是为该数组对象分配一块连续的内存空间,这块连续的内存空间的长度就是数组的长度。上面程序中的number变量在执行number = strArr;之后,会直接指向一个已经存在的数组,因此number变量可以使用。Java程序中的引用变量并不需要经过所谓的初始化操作,需要进行初始化的是引用变量所引用的对象。需要指出的是,Java的局部变量必须由程序员赋初始值,因此如果定义了局部变量的数组变量,程序必须对局部的数据变量进行赋值,即使赋值为null。
1、3 基本类型数组的初始化
对于基本类型数组而言,数组元素的值直接存储在对应的数组元素中。初始化过程为:程序直接先为数组分配内存空间,再将数组元素的值存入对应内存中。
public class ArrayTest4 {public static void main(String[] args) {int[] strArr;strArr = new int[]{1 , 2 , 3 , 4};}}上面代码对应的内存空间示意图如下所示。
实际上,不管是基本类型的变量还是引用类型的变量,都是存储在各自的方法栈中的。但引用类型的变量所引用的对象(包括数组、普通Java对象)总是存储在堆内存中。对于Java而言,堆内存中的对象通常是不允许直接访问的,为了访问堆内存中的对象,通常只能通过引用变量。
1、4 引用类型数组的初始化
引用类型数组的数组元素依然是引用类型,因此数组元素里存储的还是引用,它指向另一块内存,这块内存里存储了该引用变量所引用的对象。
class Person{ public int age; //年龄 public double height; //身高 public void info() { //自我介绍 System.out.println("年龄:" + age + ",身高:" + height); } }public class ArrayTest5 { public static void main(String[] args) { Person[] students = new Person[2]; //定义并初始化数组 Person li = new Person(); //创建一个Person实例,并赋给li变量 li.age = 13; li.height = 120.3; Person wang = new Person(); //创建一个Person实例,并赋给wang变量 wang.age = 17; wang.height = 160.5; students[0] = li; //将li变量的值赋给第一个数组元素 students[1] = wang; //将wang变量的值赋给第二个数组元素 students[0].info(); students[1].info(); }}
输出结果为:
年龄:13,身高:120.3
年龄:17,身高:160.5
执行代码之后,li和students[0]指向同一个内存去,而且它们都是引用类型的变量,因此通过li和students[0]来访问Person实例的属性和方法效果完全一样,同时,无论修改li还是students[0]的属性或者方法,势必也会相互影响,因为修改的其实是同一块内存区域。同理,wang和students[1]也是同样的效果。内存示意图如下所示。
- 数组及其内存管理——数组初始化
- 数组及其内存管理——使用数组
- 数组及其内存管理
- 23、数组及其内存管理
- Java 数组及其内存管理
- java数组及其内存管理
- 数组初始化及其遍历
- 数组及其初始化方式
- C++内存管理——指针&&数组
- C++内存管理——指针&&数组
- Java中数组、对象及其内存管理、回收
- 【J2SE快速进阶】——数组(及其内存分析 )
- 内存管理之数组
- 数组的内存管理
- 二维数组内存的初始化
- Java数组及其内存分配
- Java数组及其内存分配
- Java数组及其内存分配
- Hough变换提取直线
- 如何新建java 动态web项目(Dynamic Web Project)
- iOS的学习路线图
- mysql将两个表结果合并到一起
- Spring Cloud构建微服务架构(三)断路器
- 数组及其内存管理——数组初始化
- ems的服务太烂了,大家有别的选择的话千万别用
- 【面试题】剑指Offer-16-反转链表
- 模糊控制-模糊是什么鬼
- (IM)即时通讯协议
- HttpUrlConnection与HttpClient的认识(一)-HttpUrlConnection的使用
- mongodb 学习之添加用户及权限设置
- Android 拷贝项目的数据库文件权限命令
- vue滑动删除组件