xbhog

Java数组以及内存分配

  1. 什么数组(简)
  2. 数组初始化
    • 动态初始化
    • 静态初始化
  3. 内存分配问题(重)
  4. 数组操作的两个常见小问题

什么是数组:

定义格式:

数组类型 [] 数组名 ;

如:常用格式,其他方式自行百度;

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虚拟机要运行程序,必须要对内存进行空间的分配和管理。

分析

  1. 单个数组的内存图

  2. 多个数组的内存图

  3. 多个数组指向相同内存图

主要明确两个主要内存

  1. 栈内存:存储 --->局部变量(定义在方法中或者方法声明上的变量)

    • 特点:局部变量在使用完毕, 立即被回收
  2. 堆内存:存储 ---->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

相关文章: