Java基础知识精通数组的内存分析

目录
  • 1.数组内存图
  • 2.两个数组的内存图
  • 3.一个变量两个数组容器的内存图
  • 4.两个变量指向一个数组容器的内存图

前言:本文章主要讲解数组的内存图,更好地掌握数组以及数组调用流程,话不多说开讲。

1.数组内存图

1.一个数组的内存图

int[] arr = new int[3]; 		//刚开始定义数组arr为int型包含三位数字,初始化为0,0,0.
arr[0] = 12;  					//数组arr第一位被赋值12
arr[2] = 14;  					//数组arr第三位被赋值14
System.out.println(arr[0]);  	//12
System.out.println(arr[1]);  	//0
System.out.println(arr[2]);		//14
System.out.println(arr);		//[I@7852e922

解释

如下图:栈相当于存放数组变量的地址,堆相当于存放数组里面的元素而他们的下标就相当于房间号。

在这里我临时定义arr的地址是0x001等同于[I@7852e922。

下面我开始介绍一下数组的调用流程 :

  • 第一步刚开始定义arr为int型数组变量放在栈里,数组里面的三个元素放在堆里并初始化为0,0,0。
  • 第二步分别把12,14赋值给arr[0],arr[2]。所以我们根据栈的地址0x001去堆里找到相应的地址,找到房间号0、2并把12、14放到相应的房间号。这样数组第一位为12,第三位为14。
  • 第三步输出数组元素以及数组的地址。这个就很简单啦!从栈里找到数组arr的地址去堆里调用相应数组的元素。

调用完成之后,栈和堆里的数据就会消失。

看懂了一个数组内存图,下面几个就会看懂啦。

2.两个数组的内存图

int[] arr1 = new int[]{23,12,5}; //一开始就初始化为23、12、5。
System.out.println(arr1[0]); //23
System.out.println(arr1[1]); //12
System.out.println(arr1[2]); //5
System.out.println(arr1);    //0x001
arr1[0] = 13;  //把13赋值给arr1第一位。
System.out.println(arr1[0]);  //13
int[] arr2 = {14,18,15};    //与上面同理
System.out.println(arr2[0]); //14
System.out.println(arr2[1]); //18
System.out.println(arr2[2]); //15
System.out.println(arr2);    //0x002
arr2[1] = 12;   //赋值给arr2第二位为12
System.out.println(arr2[1]); //12
  • 这个与第一个数组不同的是数组里面的元素全部被初始化赋值。
  • 流程都一样,都是先通过栈找到数组地址根据地址去堆寻找相应数组元素。
  • 当数组arr1运行完后会退出栈和堆,给arr2让出内存空间。也就是说arr1运行完后会消失于内存,arr2数组进入内存进行操作。
  • 这两个数组的地址不一样。

3.一个变量两个数组容器的内存图

int[] arr = new int[3];		//定义一个int型的arr数组,包含三个元素初始化为0。
System.out.println(arr[0]);  // 0
arr[0] = 3;
System.out.println(arr[0]);	 //3
System.out.println(arr);     //0x001
arr = new int[5];         	//重新赋值int型的arr数组,包含5个元素初始化为0,并且数组地址也相应改变。
System.out.println(arr[0]); // 0
arr[0] = 5;
System.out.println(arr[0]); // 5
System.out.println(arr);    //0x002     如果不明白看下图
  • 这个与其他两个案例不同的是把两个数组都指向同一个变量,这就相当于往同一个杯子先放入清水然后把水喝光再放入饮料。
  • 这两个数组跟杯子是同一个道理,当arr =new int[3]执行完后会被 new int[5]数组元素所覆盖。所有的数组元素和地址会改变。
  • 执行流程跟我讲的第一个案例一样。

4.两个变量指向一个数组容器的内存图

int[] arr1 = new int[3];		//定义一个int型的arr数组,包含三个元素初始化为0。
System.out.println(arr1[0]);	//0
arr1[0] = 12;
System.out.println(arr1[0]);	//12
System.out.println(arr1);		//0x001
int[] arr2 = arr1;				//把arr1变量赋值给arr2
System.out.println(arr2[0]);	//12
arr2[0] = 13;
System.out.println(arr2[0]);	//13
System.out.println(arr2);		//0x001
System.out.println(arr1[0]);	//13
  • 这个案例与上一个案例不同的是这个案例是两个变量指向同一个数组,就相当于原本给你发顺丰快递,后来给你改发为圆通快递,但是收件人依旧是你,地址也不会发生改变。
  • 所以arr1赋值给arr2,里面的元素与数组地址都不会改变。
  • 最后程序输出arr1[0]的值实际上是arr2[0]的值。

结束语

本文章数组内存图已讲完,欢迎小伙伴们来评论区讨论。

(0)

相关推荐

  • Java十分钟掌握数组与常见异常

    数组的定义 1:单个变量能存储信息 2:用来存储具有相同数据类型的数据集合,可以使用共同的名字来引用数组中存储的数据. 特点 数组可以存储任何类型的数据,包括原始数据类型和引用数据类型,但是一旦指定了数组的类型之后,就只能用来存储指定类型的数据. 数组的使用 声明一个数组变量来存放该数组 语法 数据类型 [] 数组名 数据类型 数组名[] //声明一个int类型 名为 numebr 的数组 int [] number; int number []; //以上两种方法都可以 创建一个新的数组对象并

  • Java数组的去重

    目录 数组去重的场景 1.ES6-set 2.利用Map数据结构去重 3. 嵌套循环+splice 4. forEach + indexOf 总结 数组去重的场景 将数组var arr =[1,1,'true','true',true,true,66,66,false,false,undefined,undefined, null,null, NaN, NaN, 0, 0, 'a', 'a',{},{}]中重复的值过滤掉 1.ES6-set 使用ES6中的set是最简单的去重方法 <script

  • 关于java数组与字符串相互转换的问题

    1.char数组(字符数组)->字符串 可以通过:使用String.copyValueOf(charArray)函数实现. 举例: char[] arr={'a','b','c'}; String string =String.copyValueOf(arr); System.out.println(string); //abc 2.String数组->字符串 String[] arr ={"0123","sb","12f"}; St

  • 一篇文章告诉你如何在Java数组中插入一个字符

    目录 定义一个数组 定义插入的字符 打印插入之前字符排列顺序 假设插入位置 找到插入位置 数组数据下移 移入数值 输出数组 总结 定义一个数组 public class charInsert { public static void main(String[] args) { // 这是字符数组 char[] ch = new char[9]; ch[0] = 'a'; ch[1] = 'b'; ch[2] = 'c'; ch[3] = 'f'; ch[4] = 'g'; ch[5] = 'i'

  • 详解Java数组的四种拷贝方式

    目录 深拷贝与浅拷贝的区别 1.for循环进行拷贝 拷贝数值类型 拷贝引用类型 2.copyof/copyOfRange 拷贝数值类型 拷贝引用类型 3.arraycopy 拷贝数值类型 拷贝引用类型 4.clone 拷贝数值类型 拷贝引用类型 5.总结 深拷贝与浅拷贝的区别 假设现在有原数组A以及拷贝后的数组B,若是改变A中的某一个值,B数组随之相应的发生变化的拷贝方式称为浅拷贝,反之B数组不受影响,则称为深拷贝:简单总结一下两者的概念: 深拷贝:拷贝后,修改原数组,不会影响到新数组: 浅拷贝

  • Java数组实现动态初始化的实例详解

    概念 1.数组动态初始化只给定数组长度,系统默认初始化值. 2.格式 数据类型[] 数组名 = new 数据类型[数组长度]; int[] arr = new int[3]; 实例 package com.itheima.array; public class Demo2Array { /* 数组的动态初始化: 在初始化的时候, 需要手动指定数组的长度, 系统会为数组容器分配初始值. 动态初始化格式: 数据类型[] 数组名 = new 数据类型[数组的长度]; 注意: 打印数组变量的时候, 会打

  • Java数组操作经典例题大总结

    目录 数组中元素的求和 使用二维数组打印一个10行的杨辉三角 求数值型数组中元素的最大值.最小值.平均数.总和等 *使用简单数组 线性查找 二分法查找 冒泡排序 求一个3*3矩阵对角线元素之和 总结 数组中元素的求和 public class T02 { public static void main(String[] args) { int[][]arr=new int[][]{{1,2,3,4,5},{1,2,3,5},{8,9,7}}; int sum=0; for(int i=0;i<

  • Java数组归纳总结

    目录 一.一维数组 1.创建方法 2.初始化数组(一维数组) 二.二维数组 1.创建方法 2.初始化二维数组 三.遍历数组 四.替换元素 五.数组排序 六.数组拷贝 七.元素查询 八.排序算法 1.冒泡排序 2.直接选择排序 3.反转排序 一.一维数组 1.创建方法 数组元素类型 数组名字[]; 数组元素类型[] 数组名字; 比如: int array[];//int 类型数组 String str[];//String类型数组 我们还要给数组申请空间: 数组名字 = new 数组元素的类型[数

  • java数组实现循环队列示例介绍

    从顶部进去数据,从底部出来数据,用数组实现队列,但是下面这个队列,只能进行一次存数值,取数值,不够完善. import java.util.Scanner; public class ArrayQueueDemo { public static void main(String[]args){ //定义队列大小maxsize ArrayQueue arrayQueue=new ArrayQueue(3); Scanner scanner=new Scanner(System.in); char

  • Java基础知识精通数组的内存分析

    目录 1.数组内存图 2.两个数组的内存图 3.一个变量两个数组容器的内存图 4.两个变量指向一个数组容器的内存图 前言:本文章主要讲解数组的内存图,更好地掌握数组以及数组调用流程,话不多说开讲. 1.数组内存图 1.一个数组的内存图 int[] arr = new int[3]; //刚开始定义数组arr为int型包含三位数字,初始化为0,0,0. arr[0] = 12; //数组arr第一位被赋值12 arr[2] = 14; //数组arr第三位被赋值14 System.out.prin

  • Java基础知识精通数组的使用

    目录 1.数组 2.数组定义格式 3.访问数组 4.遍历数组 前言:本文章正式踏入数组部分,今天来讲一下数组. 1.数组 数组是一组数据结构,用来储存一组相同类型值的集合. 数组就是一个容器. 数组就是个引用数据类型. 作用: 用来装数据,方便对数据进行管理操作. 特点: 一旦创建数组,就不能改变长度. 数组里面所有的元素的类型必须是相同数据类型的. 数组中既可以储存基本数据类型,也可以存储引用数据类型. 2.数组定义格式 格式一:元素的数据类型[] 数组的名字 = new 元素的数据类型[元素

  • Java基础知识精通二维数组的应用

    目录 1.什么是二维数组 2.定义格式 3.二维数组的使用 4.二维数组的遍历 本文章主要讲二维数组定义,用法. 1.什么是二维数组 在二维数组多个元素为一维数组的数组就称为二维数组 2.定义格式 格式一: 元素的数据类型[][] 数组的名字 = new 元素的数据类型[二维数组的长度][一维数组的长度]: int[][] a = new int[3][2]; 解释: 这个二维数组中还有3个一维数组,每个一维数组中有两个元素. 格式二: 元素的数据类型[][] 数组的名字 = new 元素的数据

  • Java基础知识精通块作用域与条件及switch语句

    目录 前言 块作用域 条件语句 格式一 格式二 格式三(常用) switch语句 前言 本文章主要讲解控制流程:块作用域.条件语句.switch语句,篇幅不大,通俗易记. 块作用域 在深入学习控制结构前,须先了解块的作用. 定义:由多条Java语句组成的语句,并用一对大括号括起来. 作用:块确定了变量的作用域,一个块可以嵌套在另一个块上. 实例: package decom1; public class cuowu { public static void main(String[] args)

  • Java基础知识精通注释与数据类型及常量与变量

    目录 一. 注释 1.简介 2.类型 1.单行注释 2.多行注释 3.文档注释 3.注意事项 二.数据类型 1.简介 2.整型 3.浮点类型 4.char类型 5.boolean类型 三.常量与变量 1.常量 2.变量 一. 注释 1.简介 注释就是一种解释程序的文本,提高代码的可读性,帮助我们查找错误,不会影响程序的运行,不用担心可执行代码变得多. 2.类型 1.单行注释 单行注释是最常用的,格式://注释的内容. 用法如下: package day1; public class Demo01

  • Java基础知识精通各种运算符

    目录 前言 一.算数运算符 1.简介 2.运用 + - * / % 二.自增自减运算符 ++ – 三.赋值运算符 四.关系运算符 五.逻辑运算符 &(单与) | (单或) ^(异或) !(非) &&(双与) || (双或) 六.位运算符 七.三元运算符 前言 本文章主要集中讲解运算符,篇幅较长,请耐心看完绝对通俗易懂. 一.算数运算符 1.简介 再Java中,使用算术运算符 +.-.*./.%分别代表加减乘除,取模. 2.运用 + 在java中+有三种:1.正常的运算.2.作为正负

  • Java基础知识精通循环结构与break及continue

    目录 前言 for循环(常用) 1.格式 2.控制流程 3.注释 while循环(常用) 1.格式 2.执行流程 do…while循环 执行流程 区别 break与continue用法 break continue 循环嵌套 前言 本文章主要讲解剩余的控制结构:for循环.while循环,话不多说直接开讲. for循环(常用) for循环是支持迭代的一种通用结构,由一个计数器换或类似的变量控制迭代次数,每次迭代后这个变量会更新.详情见实例1: 1.格式 for(初始化条件;判断条件;控制条件)

  • Java基础知识汇总

    Java基础知识 1.Java语言的优点: 1)Java是纯面向对象语言 2)与平台无关性,一次编译到处运行 3)Java提供了狠多内置类库 4)提供了对web应用的支持 5)具有较好的安全性(数组边界检测.Bytecode检测)和健壮性(强制型机制.垃圾回收器.异常处理) 6)去除c++难以理解的一些特性(头文件 指针 运算符重载 多重继承) 2.java与c++的异同: 1)Java为解释型语言,c++为编译型语言,java会慢但是跨平台 2)Jave为纯面向对象,c++既面向对象又能面向过

  • Java基础知识之成员变量和局部变量浅显易懂总结

    目录 引言 java变量分类 JVM中的主要内存空间 三大变量内存分配情况 三区介绍 栈区 堆区 方法区 基本介绍 成员变量 局部变量 变量使用 总结 引言 成员变量和局部变量在每种编程语言中都有涉及,如果之前了解过其他语言的成员变量或者局部变量,那么在学习java中的成员变量和局部变量时可以看看有那些联系和不同,这一块的东西也不能说难,如果第一次接触可能会感觉有点乱,所以接下来我先把java中总结的成员变量和局部变量的部分内容先列出来,带着这些内容学起来会轻松很多! java变量分类 JVM中

  • java 基础知识之IO总结

    java  基础知识之IO总结     我计划在接下来的几篇文章中快速回顾一下Java,主要是一些基础的JDK相关的内容. 工作后,使用的技术随着项目的变化而变化,时而C#,时而Java,当然还有其他一些零碎的技术.总体而言,C#的使用时间要更长一些,其次是Java.我本身对语言没有什么倾向性,能干活的语言,就是好语言.而且从面向对象的角度来看,我觉得C#和Java对我来说,没什么区别. 这篇文章主要回顾Java中和I/O操作相关的内容,I/O也是编程语言的一个基础特性,Java中的I/O分为两

随机推荐