数组和内存控制

简介:

数组和内存控制

一、 数组初始化:

a) 静态初始化: 初始化时由程序员指定数组元素值;系统会自动决定该数组的长度。

b) 动态初始化: 初始化时,程序员指定数组的长度,系统默认为数组元素赋初始化。

//采用静态初始化方式初始化第一个数组
String[] books = new String[]
{
"仓央嘉措诗集",
"人生若只如初见",
"当时只道是寻常"
};
//采用静态初始化的简化形式初始化第二个数组
String[] names = 
{
"斗鬼神",
"杀破狼",
"铁碎牙"
};
//采用动态初始化的语法初始化第三个数组
String[] strArr = new String[5];
//访问3个数组的长度
System.out.println("第一个数组的长度:" + books.length);
System.out.println("第二个数组的长度:" + names.length);
System.out.println("第三个数组的长度:" + strArr.length);

注意观察strArr这个变量,该变量使用动态初始化方式,所以每个元素的值为系统默认赋予初始值。

Java系统默认指定初始值的规则如下:

整形(byte,short,int long): 数组元素默认为0

浮点型(float,double): 数组元素默认值为0.0

字符型(char): 数组元素默认值为:’\u0000’;

布尔型(boolean): 数组元素默认值为false

引用类型(类、接口、数组) : 数组元素默认值为null

 

注意点: 对一个数组进行初始化时,不要同时使用静态初始化和动态初始化,即不要即指定数组的长度,又为每个元素分配初始值。

 

二、 数组长度不变:

a) 数组初始化完成后,数组的长度不可改变; 程序可以改变数组引用变量应用的地址,但不能改变堆内存中已有数组的长度。

b) 数组长度: arr.length

 

三、 基本类型数组初始化:

基本类型的数组,数组元素的值直接存储在对应的数组元素中: 程序为数组元素分配内存空间,再将数组元素的值存入对应的内存中。

//定义一个int[]类型的数组变量
int[] iArr;
//静态初始化数组,数组长度为4
iArr = new int[]{2 , 5 , -12 , 20};

程序首先会在方法栈中定义一个iArr的引用变量,此时该变量尚未指向任何有效的堆内存,所以无法使用该引用变量。

之后,程序执行静态初始化,在堆内存中开辟了四块内存空间,分别存储每一个数组元素的值; 空间开辟完成后,数组的长度不可改变。

iArr引用变量将指向堆内存中开辟的空间,可以也只能通过该引用变量来访问操作堆内存空间中的数据。

 

注意: 所以方法中的变量都是存储在方法栈内存中的; 所有引用变量的值都是存储在堆内存中。

 

四、 引用类型数组初始化:

引用类型的数组是指数组元素仍然为引用类型,指向另一块堆内存空间,这块堆内存空间里存储了该引用变量所引用的对象。

class Person
{
	//年龄
	public int age;
	//身高
	public double height;
	//定义一个info方法
	public void info()
	{
		System.out.println("我的年龄是:" + age + ",我的身高是:" + height);
	}
}
public class ReferenceArrayTest
{
	public static void main(String[] args) 
	{
		//定义一个students数组变量,其类型是Person[]
		Person[] students;
		//执行动态初始化
		students = new Person[2];
		System.out.println("students所引用的数组的长度是:" + students.length);
		//创建一个Person实例,并将这个Person实例赋给zhang变量
		Person zhang = new Person();
		//为zhang所引用的Person对象的属性赋值
		zhang.age = 15;
		zhang.height = 158;
		//创建一个Person实例,并将这个Person实例赋给lee变量
		Person lee = new Person();
		//为lee所引用的Person对象的属性赋值
		lee.age = 16;
		lee.height = 161;
		//将zhang变量的值赋给第一个数组元素
		students[0] = zhang;
		//将lee变量的值赋给第二个数组元素
		students[1] = lee;
		//下面两行代码的结果完全一样,因为lee和students[1]指向的是同一个Person实例。
		lee.info();
		students[1].info();
	}
}
分析: 

程序执行Person[] students;时,jvm会在栈内存中定义一个引用变量(指针),此时的栈内存尚未指向任何有用的空间。

程序执行students = new Person[2];为students动态初始化,即在堆内存中,开辟两个内存空间,此时,系统会默认为每个数组元素分配默认的初始值null

此时的students的每个元素都是引用,且此引用并未指向任何有效的内存。

系统接下来定义了zhanglee两个引用变量,并让他们指向堆内存中的两个Person对象,此时的zhanglee两个引用变量存储在main方法栈中,而两个Person对象则存储在堆内存中。

接下来,系统让students的两个元素值(引用)分别指向zhanglee所指向的两个有用Person对象,这样,就可以通过students[0]students[1]分别访问Person对象了。

相关文章
|
3月前
|
存储 C语言 计算机视觉
在C语言中指针数组和数组指针在动态内存分配中的应用
在C语言中,指针数组和数组指针均可用于动态内存分配。指针数组是数组的每个元素都是指针,可用于指向多个动态分配的内存块;数组指针则指向一个数组,可动态分配和管理大型数据结构。两者结合使用,灵活高效地管理内存。
|
3月前
|
容器
在使用指针数组进行动态内存分配时,如何避免内存泄漏
在使用指针数组进行动态内存分配时,避免内存泄漏的关键在于确保每个分配的内存块都能被正确释放。具体做法包括:1. 分配后立即检查是否成功;2. 使用完成后及时释放内存;3. 避免重复释放同一内存地址;4. 尽量使用智能指针或容器类管理内存。
|
4月前
|
Rust 安全 Java
内存数组越界
【10月更文挑战第14天】
56 1
|
5月前
|
编译器 Linux API
基于类型化 memoryview 让 Numpy 数组和 C 数组共享内存
基于类型化 memoryview 让 Numpy 数组和 C 数组共享内存
81 0
|
5月前
|
存储 安全 Linux
将文件映射到内存,像数组一样访问
将文件映射到内存,像数组一样访问
55 0
|
9月前
|
Java
<Java SE> 5道递归计算,创建数组,数组遍历,JVM内存分配...
<Java SE> 5道递归计算,创建数组,数组遍历,JVM内存分配
85 2
|
9月前
|
存储 编译器 C语言
C陷阱:数组越界遍历,不报错却出现死循环?从内存解析角度看数组与局部变量之“爱恨纠葛”
在代码练习中,通常会避免数组越界访问,但如果运行了这样的代码,可能会导致未定义行为,例如死循环。当循环遍历数组时,如果下标超出数组长度,程序可能会持续停留在循环体内。这种情况的发生与数组和局部变量(如循环变量)在内存中的布局有关。在某些编译器和环境下,数组和局部变量可能在栈上相邻存储,数组越界访问可能会修改到循环变量的值,导致循环条件始终满足,从而形成死循环。理解这种情况有助于我们更好地理解和预防这类编程错误。
198 0
|
9月前
|
存储 机器学习/深度学习 Java
【Java探索之旅】数组使用 初探JVM内存布局
【Java探索之旅】数组使用 初探JVM内存布局
88 0
|
9月前
|
存储 搜索推荐 编译器
C learning_11 (数组和在内存存储的理解、数组越界、数组作为形参)
C learning_11 (数组和在内存存储的理解、数组越界、数组作为形参)
|
9月前
深度解析指针与数组:探索内存管理的艺术
深度解析指针与数组:探索内存管理的艺术
89 0