Java数组以及内存分配
Java数组以及内存分配
- 什么数组(简)
- 数组初始化
- 动态初始化
- 静态初始化
- 内存分配问题(重)
- 数组操作的两个常见小问题
什么是数组:
定义格式:
数组类型 [] 数组名 ;
如:常用格式,其他方式自行百度;
int[] arr;
double[] arr;
float[] arr;
数组初始化:
动态初始化格式:
数据类型[] 数组名 = new 数据类型[数组长度/数组元素个数]
如:
int[] arr =new int[6];
double[] arr = new double[6];
等号左边:
int:数组的数据类型
[]:代表这是一个数组
arr:代表数组的名称
等号右边:
new:为数组开辟内存空间
int:数组的数据类型
[]:代表这是一个数组
6:代表数组的长度
示例代码:
public class CsArrays {
public static void main(String[] args) {
//动态初始化
int[] arr = new int[6];
System.out.println(arr);
System.out.println(arr[0]);
System.out.println(arr[1]);
arr[0] =100;
arr[1] =200;
System.out.println(arr);
System.out.println(arr[0]);
System.out.println(arr[1]);
}
}
静态初始化格式:
数据类型[] 数组名 = {元素、元素、.....}
int[] arr = {};
double[] arr = {};
示例代码:
public class JingTai {
public static void main(String[] args) {
int[] arr = {1,2,3};
System.out.println(arr[0]);
System.out.println(arr[1]);
System.out.println(arr[2]);
}
}
内存分配的问题:
前提:
内存是计算机中的重要原件,临时存储区域,作用是运行程序。
我们编写的程序是存放在硬盘中的,在硬盘中的程序是不会运行的。
必须放进内存中才能运行,运行完毕后会清空内存。
Java虚拟机要运行程序,必须要对内存进行空间的分配和管理。
分析:
单个数组的内存图
多个数组的内存图
多个数组指向相同内存图
主要明确两个主要内存:
栈内存:存储 --->局部变量(定义在方法中或者方法声明上的变量)
- 特点:局部变量在使用完毕, 立即被回收
堆内存:存储 ---->new出来的东西(实体, 对象)
- 特点:对象在使用完毕, 在垃圾回收器空闲时回收掉
首先一个数组在Java虚拟机中的内存分配情况:

解:
按照上面的分析:左边栈内存存放的是局部变量,所以int[] arr在左边;右边堆内存存放的new出来的数据;由栈内存指向堆内存,并将堆内存中的对象内存地址赋给定义的数组;刚开始创建的内存空间int类型默认为0;所以第一次输出的情况是:0 0 0;
数组创建完成后,对数组中的元素的进行赋值;arr[0]、arr[2] 通过地址值找到堆中对应的地址值,将 arr[0]、arr[2] 进行重新赋值,在内存中指向不变,但是将原来的0-->100/200;再输出则出现赋值后的值;
两个数组在Java中的内存分配情况:

解:
基本逻辑与一个数组的内存分配情况大体相同,现在是定义两个数组,在初始化数组时按照在堆内存开辟不同的空间地址进行数据元素的分配,如上图可视;
两个数组指向同一个地址的内存分配情况(重点):

如图所示,初始化数组 arr,然后进行赋值操作。输出即为:100、200、300。
当定义数组 arr2 的时候把第一个数组 arr 的地址值赋给第二个数组,arr2 数组会根据地址值找到堆内存中的 arr 的地址及,
然后给第二个数组进行赋值,会将原来 arr 的数值进行覆盖,所以当我们再次打印 arr 和 arr2 的数据时候,会出现一样的数据。
数组操作的两个常见小问题
索引越界异常
出现原因
public class ArrayDemo {
public static void main(String[] args) {
int[] arr = new int[3];
System.out.println(arr[3]);
}
}
数组长度为3,索引范围是0~2,但是我们却访问了一个3的索引。
程序运行后,将会抛出ArrayIndexOutOfBoundsException 数组越界异常。在开发中,数组的越界异常是不能出现的,一旦出现了,就必须要修改我们编写的代码。
解决方案
将错误的索引修改为正确的索引范围即可!
空指针异常
出现原因
public class ArrayDemo {
public static void main(String[] args) {
int[] arr = new int[3]; //把null赋值给数组
arr = null;
System.out.println(arr[0]);
}
}
arr = null 这行代码,意味着变量arr将不会在保存数组的内存地址,也就不允许再操作数组了,因此运行的时候会抛出 NullPointerException 空指针异常。在开发中,数组的越界异常是不能出现的,一旦出现了,就必须要修改我们编写的代码。
解决方案
给数组一个真正的堆内存空间引用即可。
图片原文地址:https://zhuanlan.zhihu.com/p/59515103
Java数组以及内存分配的更多相关文章
- Java数组及其内存分配
几乎所有的程序设计语言都支持数组.Java也不例外.当我们需要多个类型相同的变量的时候,就考虑定义一个数组.在Java中,数组变量是引用类型的变量,同时因为Java是典型的静态语言,因此它的数组也是静 ...
- Java 中数组的内存分配
Java 中数组的内存分配 1.Java 程序在运行时,需要在内存中分配空间.为了提高运算效率,就对空间进行了不同区域的划分,因为每一片区域都有特定的处理数据和内存管理方式. 2.数组基本概念 数组是 ...
- Java数组的内存管理
Java数组的内存管理 Java语言是典型的静态语言,因此Java的数组是静态的,即当数组被初始化之后,该数组的长度是不可变的.Java程序中的数组必须经初始化才能使用.所谓初始化,就是当数组对象的元 ...
- java程序的内存分配
java程序的内存分配 JAVA 文件编译执行与虚拟机(JVM)介绍 Java 虚拟机(JVM)是可运行Java代码的假想计算机.只要根据JVM规格描述将解释器移植到特定的计算机上,就能保证经过编译的 ...
- java程序的内存分配(一)
首 页 阅览室 馆友 我的图书馆 帐号 java程序的内存分配(一) 收藏 JAVA 文件编译执行与虚拟机(JVM)介绍 Java 虚拟机(JVM)是可运行Java代码的假想计算机.只要根据J ...
- Java数组和内存控制
1.数组初始化 1.1 Java数组是静态的 Java语言是典型的静态语言,因此Java的数组是静态的,即当数组被初始化之后,该数组的长度是不可变的.Java程序中的数组必须经初始化才可使用.所谓初始 ...
- Java变量以及内存分配
Java变量以及内存分配(非常重要) 堆栈 静态存储区域 一个由C/C++编译的程序占用的内存分为以下几个部分 1.栈区(stack)— 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等.其操 ...
- Java当中的内存分配以及值传递问题内存解析
首先必须说明作为Java程序员对于内存只要有大致的了解就可以了,如果你对Java当中的某一个知识点在不需要分析内存分配过程的情况下可以掌握,那就大可不必去研究内存.如果你对知识点已经掌握,那么你应该把 ...
- C++二维数组动态内存分配
对于二维数组和二维指针的内存的分配 这里首选说一下一维指针和一维数组的内存分配情况. 一维: 数组:形如int a[5];这里定义了一个一维数组a,并且数组的元素个数是5,这里的a是这五个元素的整体 ...
随机推荐
- Maxscript中渲染中文版Vray完成贴图(VrayCompleteMap)的方法
Objbakeproperties = $.INodeBakeProperties; --选定对象的烘培节点 Prjbakeproperties = $.INodeBakeProjProperties ...
- Django:给requests发送请求功能 套一层衣服。
个人的疑问
- Charles安装教程
一, 简介及安装 —,charles的使用 1.1 charles的说明 Charles其实是一款代理服务器,通过过将自己设置成系统(电脑或者浏览器)的网络访问代理服务器,然后截取请求和请求结果达 ...
- .NET CORE命令行
目录 0. 基础命令行 1. 基础命令 2. SDK命令 3. 使用命令行创建. net Core项目 shanzm-2020年9月7日 22:00:00 0. 基础命令行 D:默认路径跳转到D盘 c ...
- 项目实战:Qt+Ffmpeg+OpenCV相机程序(打开摄像头、支持多种摄像头、分辨率调整、翻转、旋转、亮度调整、拍照、录像、回放图片、回放录像)
若该文为原创文章,未经允许不得转载原博主博客地址:https://blog.csdn.net/qq21497936原博主博客导航:https://blog.csdn.net/qq21497936/ar ...
- LayUi超级好用的前端工具
日期:https://www.layui.com/laydate/ LayUi 首页地址:https://www.layui.com/
- leetcode刷题-86分隔链表
题目 给定一个链表和一个特定值 x,对链表进行分隔,使得所有小于 x 的节点都在大于或等于 x 的节点之前. 你应当保留两个分区中每个节点的初始相对位置. 示例: 输入: head = 1->4 ...
- 容器服务 TKE 上服务暴露的几种方式
预备知识 1. K8S 上 Service 类型 ClusterIP 通过集群的内部 IP 暴露服务,选择该值,服务只能够在集群内部可以访问,这也是默认的 ServiceType. NodePort ...
- [ArcGIS]高程地图-把DEM栅格数据(.tif)转换为TIN矢量数据,并储存TIN数据。
把DEM数据(.tif)获得栅格数据对应的经纬度及高程信息,存到地理数据库 一.预处理工作 栅格数据的合并--目的:将原始4张Dem(.tif)数据合并为一张Dem(.tif) https://wen ...
- Scala的递归函数应用
使用递归函数实现累加: def sum(nums:Int*):Int={ if(nums.length == 0) 0 else nums.head + sum(nums.tail:_*) } 结果为 ...