Java 笔记 13:Java 数组内容,数组的声明、创建、初始化、赋值等,以及内存分析

一、前言

记录时间 [2024-05-03]

系列文章简摘:
Java 笔记 01:Java 概述,MarkDown 常用语法整理
Java 笔记 02:Java 开发环境的搭建,IDEA / Notepad++ / JDK 安装及环境配置,编写第一个 Java 程序
Java 笔记 11:Java 方法相关内容,方法的设计原则,以及方法的定义和调用
Java 笔记 12:Java 方法的相关使用,方法重载、参数传递,以及递归等内容

更多 Java 相关文章,请参考上面专栏哦。

本文讲述 Java 数组相关知识,包括数组的声明和创建 、以及数组的简单使用 。此外,文章对 Java 内存进行分析,从内存的角度分析了数组创建的过程。

二、数组概述

Java 中的数组是一种数据结构,用于存储同一类型的多个元素。

数组在 Java 中被定义为一个对象,具有固定的长度,并且可以容纳各种数据类型,包括原始数据类型和引用数据类型。

  • 数组是相同类型数据的有序集合;
  • 数组描述的是相同类型的若干个数据,按照一定的先后次序排列组合而成;
  • 每一个数据称作一个数组元素,每个数组元素可以通过一个下标来访问
  • 数组的下标从 0 开始

使用数组可以避免定义多个重复的同种类型变量。

三、数组声明和创建

在 Java 中,声明数组创建数组可以一起完成,也可以分开进行。

1. 数组声明

必须先声明数组变量,然后才能在程序中使用数组 。声明数组变量的语法是指定数组类型和数组名称。下面是声明数组变量的语法:

java 复制代码
// 首选方法
dataType[] arrayRefVar;

// 另一种方法,效果相同
dataType arrayRefVar[];

// 例如,声明一个整型数组变量
int[] myArray;

这两种形式都可以用来声明数组变量,它们是等价的,没有功能上的区别。

但通常建议使用 dataType[] arrayRefVar; 的形式,因为它更符合 Java 编程的传统风格,并且更容易让人理解。

2. 数组创建

在 Java 中,使用 new 操作符来创建数组是一种常见的做法。new 操作符用于在堆内存中动态创建对象或数组实例。

创建数组语法如下:

java 复制代码
// 声明和创建同时完成
// arraySize 指定数组长度
dataType[] arrayRefVar = new dataType[arraySize];

// 先声明,后创建
dataType[] arrayRefVar;
arrayRefVar = new dataType[arraySize];

// 例如,创建一个长度为 5 的整型数组
// 可以存放 5 个 int 类型的数字
int[] myArray = new int[5];

在这个例子中,new 操作符创建了一个长度为 5 的整型数组,并将其引用赋值给了 myArray 变量。这个数组会在堆内存中被动态分配空间。

创建数组时需要指定数组的长度

四、数组简单使用

1. 数组索引

在 Java 中,数组索引用于访问数组中的元素。数组索引从 0 开始,因此第一个元素的索引是 0,第二个元素的索引是 1,以此类推。

可以使用方括号 [] 来指定数组中的索引位置。

示例代码如下:

java 复制代码
int[] myArray = {10, 20, 30, 40, 50};

// 访问数组中的第一个元素(索引为 0)
int firstElement = myArray[0]; // firstElement 的值为 10

// 访问数组中的第三个元素(索引为 2)
int thirdElement = myArray[2]; // thirdElement 的值为 30

在这个例子中,myArray[0] 表示访问数组 myArray 中的第一个元素,而 myArray[2] 表示访问数组中的第三个元素。

需要注意的是,如果尝试访问超出数组范围的索引位置,将会导致 ArrayIndexOutOfBoundsException 异常。因此,在使用数组时应当确保索引值在合法的范围内。

2. 数组长度

在 Java 中,可以使用数组的 length 属性来获取数组的长度。这个属性返回数组中元素的数量,即数组的大小。

示例代码如下:

java 复制代码
// 创建并初始化数组
int[] myArray = {10, 20, 30, 40, 50};

// 获取数组的长度,即 5
int arrayLength = myArray.length; 

在这个例子中,myArray.length 返回数组 myArray 中元素的数量,即 5。

  • length 是数组的属性,而不是方法,因此不需要使用括号。
  • 这个属性对于确定数组的大小,以及遍历数组非常有用。
  • 数组的长度是固定的,一旦创建了数组并分配了空间,就不能再改变它的长度。

3. 数组初始化

数组的初始化可以分为静态初始化动态初始化两种方式。

其中,动态初始化包含默认初始化。

静态初始化

在静态初始化中,可以在声明数组的同时为其赋初值。它的语法简洁,适用于已经知道数组初始值的情况。

静态初始化时,不需要指定数组的大小,编译器会根据提供的初始值自动确定数组的长度。

普通类型的静态初始化,示例代码如下:

java 复制代码
// 声明并静态初始化一个整型数组
int[] myArray = {10, 20, 30, 40, 50};

在这个例子中,myArray 是一个整型数组,它包含了 5 个元素,并且每个元素的值分别为10、20、30、40 和 50。


引用类型的静态初始化

静态初始化对于引用类型的数组也同样适用,不需要显式指定数组的大小,编译器会根据提供的初始值自动确定数组的长度。

对于引用类型的数组,静态初始化方式与基本类型数组类似。可以在声明数组时直接为其赋予初始值,示例代码如下:

java 复制代码
// 声明并静态初始化一个字符串数组
String[] myArray = {"apple", "banana", "orange"};

在这个示例中,myArray 是一个字符串数组,包含了3个元素,分别是 "apple"、"banana" 和 "orange"。


引用其他类的对象

如果想要在静态初始化数组时引用其他类的对象,可以像下面这样做:

java 复制代码
// 假设有一个名为 Person 的类
class Person {
    String name;
    int age;

    // 构造函数
    Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
}

// 在静态初始化中引用 Person 类的对象
Person[] people = {
    new Person("Alice", 25),
    new Person("Bob", 30),
    new Person("Charlie", 35)
};

在这个例子中:

  • people 是一个 Person 类型的数组,包含了三个 Person 对象;
  • 每个对象都通过 new Person(...) 创建并初始化;
  • 每个 Person 对象都有一个名字 name 和年龄 age 属性。

这样就可以在静态初始化数组时引用其他类的对象了。

动态初始化

动态初始化数组是在声明数组后,使用 new 关键字为数组分配内存空间,并为数组元素赋初始值的一种方式。

相比于静态初始化,动态初始化更加灵活,可以在运行时确定数组的大小以及元素的值。

需要注意的是,动态初始化的数组长度必须是一个非负的整数值。

示例代码如下:

java 复制代码
// 声明一个整型数组
int[] myArray;

// 使用 new 关键字动态初始化数组,并指定数组的长度为 5
myArray = new int[5];

// 为数组元素赋值
myArray[0] = 10;
myArray[1] = 20;
myArray[2] = 30;
myArray[3] = 40;
myArray[4] = 50;

在这个例子中:

  • 首先声明了一个整型数组变量 myArray
  • 然后使用 new 关键字为其分配了一个长度为 5 的内存空间;
  • 之后,通过索引为数组元素赋值。

这种方式下,可以在运行时确定数组的大小,也可以根据具体需求为数组元素赋值。

默认初始化

在 Java 中,如果声明了一个数组但没有对其进行显式初始化,那么 Java 会对数组进行默认初始化。

默认初始化,也叫隐式初始化,是指给数组的元素赋予初始值,这个初始值取决于数组元素的类型。

需要注意的是,在使用数组之前,最好对其进行显式初始化,以避免出现意外的错误。

对于基本数据类型的数组,如果没有进行显式初始化,Java 会将数组的每个元素初始化为该基本数据类型的默认值

例如:

  • 整型数组的默认值为 0
  • 浮点型数组的默认值为 0.0
  • 布尔型数组的默认值为 false
  • 字符型数组的默认值为 '\u0000'(空字符)

示例代码如下:

java 复制代码
// 整型数组的默认值为 0
int[] intArray = new int[3];
System.out.println(Arrays.toString(intArray)); // 输出:[0, 0, 0]

// 浮点型数组的默认值为 0.0
double[] doubleArray = new double[3];
System.out.println(Arrays.toString(doubleArray)); // 输出:[0.0, 0.0, 0.0]

// 布尔型数组的默认值为 false
boolean[] booleanArray = new boolean[3];
System.out.println(Arrays.toString(booleanArray)); // 输出:[false, false, false]

// 字符型数组的默认值为 '\u0000'(空字符)
char[] charArray = new char[3];
System.out.println(Arrays.toString(charArray)); // 输出:空字符

对于引用数据类型的数组,默认值为 null

示例代码如下:

java 复制代码
// 引用数据类型的数组,默认值为 null
String[] stringArray = new String[3];
System.out.println(Arrays.toString(stringArray)); // 输出:[null, null, null]

4. 数组元素赋值

在 Java 中,数组元素赋值的方式有两种:索引或初始化。

如果数组中的元素没有被赋初值,那么它的默认值为 0。

通过索引为数组元素赋值:

可以通过索引来为数组元素赋值。可以使用方括号 [] 加上索引来指定要赋值的元素位置,然后将新值赋给该位置。

示例代码如下:

java 复制代码
int[] myArray = new int[5]; // 创建一个长度为5的整型数组

// 为数组元素赋值
myArray[0] = 10;	// 下标从 0 开始,给第一个元素赋值为 10
myArray[1] = 20;
myArray[2] = 30;
myArray[3] = 40;
myArray[4] = 50;

在这个例子中,通过 myArray[索引] 的形式,为数组 myArray 中的每个元素赋了一个值。

索引从 0 开始,因此 myArray[0] 表示数组中的第一个元素,myArray[1] 表示第二个元素,以此类推。


初始化赋值:

如果已经在声明数组时进行了初始化,也可以在初始化的同时为数组元素赋值,例如:

java 复制代码
// 创建并初始化数组
int[] myArray = {10, 20, 30, 40, 50}; 

这样的话,数组的每个元素都被赋了初始值。

五、案例分析

1. 计算数组所有元素和

要计算数组中所有元素的和,可以使用一个循环来遍历数组,并将每个元素的值加起来。

下面是一个计算数组所有元素和的示例代码:

java 复制代码
int[] myArray = {10, 20, 30, 40, 50};
int sum = 0;

// 遍历数组并计算所有元素的和
for (int i = 0; i < myArray.length; i++) {
    sum += myArray[i];
}

System.out.println("数组所有元素的和为:" + sum);

在这个例子中:

  • 首先创建了一个整型数组 myArray,然后初始化了它。
  • 接下来,定义一个变量 sum 用来存储所有元素的和,并初始化为 0。
  • 然后,使用一个 for 循环遍历数组 myArray,将每个元素的值加到 sum 中。
  • 最后,输出数组所有元素的和。

六、内存分析

进行内存分析时,可以通过各种工具和技术来监视和分析程序的内存使用情况,包括但不限于 JVM 内置的工具(如 jvisualvm、jconsole)、第三方工具(如 VisualVM、YourKit Java Profiler)以及分析内存转储文件(Heap Dump)等。

1. Java 内存分析

在 Java 中进行内存分析通常涉及以下几个方面:

  • 堆内存(Heap Memory): 堆内存是用于存储对象实例 的地方。
    • 所有通过 new 关键字创建的对象都存储在堆内存中,比如数组;
    • 可以被所有的线程共享,不会存放别的对象引用;
    • 堆内存的大小可以通过 JVM 启动参数进行设置;
    • 垃圾回收器负责在堆内存中回收不再使用的对象以释放内存空间。
  • 栈内存(Stack Memory): 栈内存用于存储方法调用和局部变量
    • 存放基本变量类型:包含这个基本类型的具体数值;
    • 引用对象的变量:存放这个引用在堆里面的具体地址;
    • 每个线程都有自己的栈内存,用于存储线程的方法调用栈和局部变量;
    • 方法调用时,方法的参数和局部变量会被分配到栈内存中;
    • 当方法执行完毕时,栈帧会被弹出栈,释放内存空间。
  • 方法区(Method Area): 方法区是存储类信息、常量、静态变量等数据的地方。
    • 可以被所有的线程共享;
    • 包含了所有的 class 和 static 变量;
    • 在方法区中存储的内容包括类的字节码、方法和字段信息、运行时常量池等;
    • 方法区在 JVM 启动时被分配,一般大小固定。

2. 数组创建过程

接下来绘图分析数组创建时,在内存中完成了哪些步骤。

代码中的流程

在代码中,我们完成了 3 个步骤:声明、创建、赋值。

java 复制代码
// 1. 声明一个整型数组变量
int[] myArray;

// 2. 创建一个长度为 5 的整型数组
int[] myArray = new int[5];

// 3. 为数组元素赋值
myArray[0] = 10;	// 下标从 0 开始,给第一个元素赋值为 10
myArray[1] = 20;
myArray[2] = 30;
myArray[3] = 40;
myArray[4] = 50;

内存中体现

如图所示,在内存中,这 3 个步骤一一对应。

步骤 1:

声明一个整型数组变量 myArray,变量 myArray 被压入栈中。

java 复制代码
// 1. 声明一个整型数组变量
int[] myArray;

在内存中的体现:


步骤 2:

创建一个长度为 5 的整型数组,在堆中开辟一片空间给它。空间中可以存放 5 个 int 型数据,索引下标从 [0] 开始。数组元素默认赋值为 0。

java 复制代码
// 2. 创建一个长度为 5 的整型数组
int[] myArray = new int[5];

在内存中的体现:


步骤 3:

为数组元素赋值,给第一个元素赋值为 10,第二个为 20,依此类推。

java 复制代码
// 3. 为数组元素赋值
myArray[0] = 10;	// 下标从 0 开始,给第一个元素赋值为 10
myArray[1] = 20;
myArray[2] = 30;
myArray[3] = 40;
myArray[4] = 50;

在内存中的体现:

七、总结

本文讲述 Java 数组相关知识,包括数组的声明和创建 、以及数组的简单使用 。此外,文章对 Java 内存进行分析,从内存的角度分析了数组创建的过程。

一些参考资料

狂神说 Java 零基础:https://www.bilibili.com/video/BV12J41137hu/

TIOBE 编程语言走势: https://www.tiobe.com/tiobe-index/

Typora 官网:https://www.typoraio.cn/

Oracle 官网:https://www.oracle.com/

Notepad++ 下载地址:https://notepad-plus.en.softonic.com/

IDEA 官网:https://www.jetbrains.com.cn/idea/

Java 开发手册:https://developer.aliyun.com/ebook/394

Java 8 帮助文档:https://docs.oracle.com/javase/8/docs/api/

相关推荐
Amarantine、沐风倩✨27 分钟前
设计一个监控摄像头物联网IOT(webRTC、音视频、文件存储)
java·物联网·音视频·webrtc·html5·视频编解码·七牛云存储
Kisorge1 小时前
【C语言】指针数组、数组指针、函数指针、指针函数、函数指针数组、回调函数
c语言·开发语言
路在脚下@1 小时前
spring boot的配置文件属性注入到类的静态属性
java·spring boot·sql
森屿Serien1 小时前
Spring Boot常用注解
java·spring boot·后端
轻口味2 小时前
命名空间与模块化概述
开发语言·前端·javascript
吉大一菜鸡2 小时前
FPGA学习(基于小梅哥Xilinx FPGA)学习笔记
笔记·学习·fpga开发
苹果醋33 小时前
React源码02 - 基础知识 React API 一览
java·运维·spring boot·mysql·nginx
晓纪同学3 小时前
QT-简单视觉框架代码
开发语言·qt
威桑3 小时前
Qt SizePolicy详解:minimum 与 minimumExpanding 的区别
开发语言·qt·扩张策略
Hello.Reader3 小时前
深入解析 Apache APISIX
java·apache