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. 数组声明

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

// 首选方法
dataType[] arrayRefVar;

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

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

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

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


2. 数组创建

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

创建数组语法如下:

// 声明和创建同时完成
// 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,以此类推。

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

示例代码如下:

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 属性来获取数组的长度。这个属性返回数组中元素的数量,即数组的大小。

示例代码如下:

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

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

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

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

3. 数组初始化

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

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

静态初始化

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

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

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

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

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


引用类型的静态初始化

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

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

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

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


引用其他类的对象

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

// 假设有一个名为 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 关键字为数组分配内存空间,并为数组元素赋初始值的一种方式。

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

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

示例代码如下:

// 声明一个整型数组
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’(空字符)

示例代码如下:

// 整型数组的默认值为 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

示例代码如下:

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

4. 数组元素赋值

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

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

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

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

示例代码如下:

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] 表示第二个元素,以此类推。


初始化赋值:

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

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

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


五、案例分析

1. 计算数组所有元素和

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

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

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 个步骤:声明、创建、赋值。

// 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 被压入栈中。

// 1. 声明一个整型数组变量
int[] myArray;

在内存中的体现:

在这里插入图片描述


步骤 2:

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

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

在内存中的体现:

在这里插入图片描述


步骤 3:

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

// 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/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/590546.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

C++ | Date 日期类详解

目录 简介 日期类总代码 | Date 类的定义 & 构造 & Print 类的定义 构造函数 & Print 比较类&#xff0c;如<、>、<...... 值加减类&#xff0c;如、-、、-...... 加减类具体分类 判断某个月有多少天 GetMonthDay 日期类 / &#xff08;- / -&…

场景文本检测识别学习 day08(无监督的Loss Function、代理任务)

无监督的Loss Function&#xff08;无监督的目标函数&#xff09; 根据有无标签&#xff0c;可以将模型的学习方法分为&#xff1a;无监督、有监督两种。而自监督是无监督的一种无监督的目标函数可以分为以下几种&#xff1a; 生成式网络的做法&#xff0c;衡量模型的输出和固…

protobuf在配置文件管理上的应用

TextFormat::ParseFromString 是 Google Protocol Buffers&#xff08;通常简称为 Protobuf&#xff09;库中的一个函数&#xff0c;用于从文本格式解析消息。Protobuf 是一种用于序列化结构化数据的库&#xff0c;它允许你定义数据的结构&#xff0c;然后自动生成源代码来处理…

【实用推荐】7个靠谱赚钱软件,宅家也能轻松赚钱!

在数字化浪潮下&#xff0c;如何在家轻松赚取收益成为许多人关注的焦点。软件市场的蓬勃发展为我们提供了多种选择&#xff0c;但面对琳琅满目的赚钱应用&#xff0c;许多人感到无从下手&#xff0c;担心选择不当。本文将为您揭示这些软件背后的奥秘&#xff0c;助您找到最适合…

【副本向】高等级副本全流程开发

副本的创建 1.从配置表通过副本ID获取此副本参数 Tab_CopyScene rCopyScene TableManager.GetCopySceneByID(m_CopySceneID);if (rCopyScene ! null){//只要配置了组队的Rule&#xff0c;就是组队模式&#xff0c;否则就是单人模式bool bSolo true;for (int n 0; n < rCo…

禅道项目管理系统 身份验证漏洞分析QVD-2024-15263

前言 最近不怎么更新了&#xff01;向小伙伴说明下 我不是什么组织 更不什么经销号&#xff08;尽管csdn有很多经销广告号&#xff09; 一确实是下岗了&#xff01;忙着为找工作而发愁。简历都投出去如同石沉大海能不愁吗!.哎...... 二是忙着论文及材料的事...…

观察者模式实战:解密最热门的设计模式之一

文章目录 前言一、什么是观察者模式二、Java实现观察者模式2.1 观察者接口2.2 具体观察者2.3 基础发布者2.4 具体发布者2.5 消息发送 三、Spring实现观察者模式3.1 定义事件类3.2 具体观察者3.3 具体发布者3.4 消息发送 总结 前言 随着系统的复杂度变高&#xff0c;我们就会采…

电商独立站最重要的功能设置:多语言转换和代运系统搭建

什么是独立站&#xff1f; 多语言模式切换 1 搭建电商独立站在我看来最简单的理解&#xff0c;就是独立的网站。 如果你在跨境圈子呆了一段时间&#xff0c;独立站是一个避不开且火热的一个词&#xff0c;并且也是所有的B2B、B2C商家都在运营和布局的市场。 独立站的优势有哪…

AI视频教程下载:零代码创建AI智能体、AI Agents和ChatGPT的Gpts

这门课程专注于提示工程的掌握&#xff0c;教你以精确的方式引导GPT&#xff0c;利用它们的生成能力产生卓越的AI驱动结果。一步一步地&#xff0c;你将学会创建多样化的GPT军团——每个都设计来满足特定的专业需求。 从提供个性化职业变更指导的职业教练AI&#xff0c;到以惊…

精准测试-Vue前端调用链影响变更分析之一

Vue前端调用链影响变更分析之一 一、背景二、工具调研1、 工具介绍&#xff1a;2、工具使用 三、工具落地集成方案&#xff08;待后续补充&#xff09;变更影响较为简单的实现变更影响较为复杂的实现1、全局关系数据库的构建2、变更影响的简单实现3、变更影响的复杂实现 一、背…

【LinuxC语言】系统日志

文章目录 前言一、系统日志的介绍二、向系统日志写入日志信息三、示例代码总结 前言 在Linux系统中&#xff0c;系统日志对于监控和排查系统问题至关重要。它记录了系统的运行状态、各种事件和错误信息&#xff0c;帮助系统管理员和开发人员追踪问题、进行故障排除以及优化系统…

(Microsoft SQL Server,错误: 233)

错误信息: A connection was successfully established with the server, but then an error occurred during the pre-login handshake. (provider: Shared Memory Provider, error: 0 - 管道的另一端上无任何进程。) (Microsoft SQL Server&#xff0c;错误: 233) 原因&…

《十三》QT绘图原理双缓冲机制

一、原理与设计 所谓双缓冲机制&#xff0c;是指在绘制控件时&#xff0c;首先将要绘制的内容绘制在一个图片中&#xff0c;再将图片一次性地绘制到控件上。在早期的 Qt 版本中&#xff0c;若直接在控件上进行绘制工作&#xff0c;则在控件重绘时会产生闪烁地现象&#xff0c;控…

零基础学习数据库SQL语句之定义数据库对象的DDL语句

DDL语句 DDL Date Definition Language 数据定义语言&#xff0c;用来定义数据库对象&#xff08;数据库&#xff0c;表&#xff0c;字段&#xff09; 基本操作 数据库操作 查询所有数据库 SHOW DATEBASES查询当前数据库 SELECT DATEBASE() 创建 CREATE DATEBASE [IF …

利用大语言模型(KIMI)构建智能产品的控制信息模型

数字化的核心是数字化建模&#xff0c;为一个事物构建数字模型是一项十分复杂的工作。不同的应用场景&#xff0c;对事物的关注重点的不同的。例如&#xff0c;对于一个智能传感器而言&#xff0c;从商业的角度看&#xff0c;产品的信息模型中应该包括产品的类型&#xff0c;名…

Mysql的关联查询以及语句

一、mysql的连接查询 1、等值连接 这里是三张表的等值连接 select rp.role_id,rp.permission_id from role_permission rp, role r, permission p where rp.role_idr.id and rp.permission_idp.id 2、内连接&#xff1a; 角色&#xff1a;系统管理员 是否拥有权限&#xf…

DHCPv4_CLIENT_ALLOCATING_03: 发送DHCPREQUEST - 必须包含‘服务器标识符‘

测试目的&#xff1a; 验证客户端发送的DHCPREQUEST消息中是否包含“服务器标识符”选项&#xff0c;以指示它选择的服务器。 描述&#xff1a; 本测试用例旨在确保DHCP客户端在广播DHCPREQUEST消息时&#xff0c;必须包含“服务器标识符”选项。该选项用于指明客户端选择了…

2024-5-1我把QQ群聊天记录分析工具重写了一下

【下载地址】 https://www.lanzoub.com/b00rn0g47e 密码:9hww 【项目背景】 2020年我用Tkinter写过一个QQ群聊天记录分析的工具exe&#xff0c;后续也写过一个纯JS前端的版本&#xff0c;前阵子有个用户反馈不能用了&#xff0c;顺便看能不能加入一个分析关键词的功能&…

第76天:WAF攻防-信息收集识别被动探针代理池仿指纹白名单

目录 基础知识 案例一: 信息收集-被动扫描-黑暗引擎&三方接口 案例二: 信息收集-目录扫描-Python 代理加载脚本 案例三: 信息收集-爬虫扫描-Awvs&Xray&Goby内置 基础知识 什么是 WAF &#xff1f; Web Application Firewall &#xff08; web 应用防火墙&am…

jvm垃圾回收机制介绍

JVM&#xff08;Java虚拟机&#xff09;是Java程序的运行环境&#xff0c;它负责执行字节码文件。JVM的工作原理主要包括以下几个部分&#xff1a;类加载器、执行引擎、垃圾收集器和内存管理。类加载器负责加载字节码文件并将其转换成Java平台上的机器码&#xff0c;执行引擎负…