• Java进阶数组与内存控制


    Java进阶——数组与内存控制

    下面将会深入探讨Java数组的静态特征。使用Java数组前必须对数组进行初始化,初始化的过程即给数组的所有元素都分配合适的内存空间,并指定初始值的过程。数组初始化以后将不能重新改变数组对象在内存中的位置和大小。从用法角度看,数组元素相当于普通变量,程序既可以吧数组的值赋给普通变量,也可以把普通变量的值赋给数组元素。但其实质是对内存中数组元素对象的操作。

    1、数组初始化

    Java语言是典型的静态语言,所以Java的数组也是静态的。Java中的数组必须经初始化后才可以使用,初始化即为数组对象的所有元素分配一个连续的内存空间,并为每个元素指定初始值。数组的初始化有两种方式:

    >静态初始化:由程序员显式地指定每个数组元素的初始值,由系统决定数组的长度;

    >动态初始化:程序员只指定数组长度,由系统为数组元素分配初始值。

    下面是两种初始化方式的实例:

    public class test01 {

           public static void main(String[] args) {

                  //静态初始化数组

                  String[] str0 = new String[]{"小武灵灵" , "41009160"};

                  //静态初始化的简化形式

                  String[] str1 = {"小武灵灵" , "41009160"};

                  //动态初始化

                  String[] str2 = new String[2];

           }

    }

    Java语言的数组变量是引用类型的变量,上面的三个数组变量按照声明的前后顺序(注意这里不是初始化的先后顺序)存储在main栈区中,其引用的数组是按照数组元素的顺序分别在堆内存中分配到长度为2的连续空间。

    注意,虽然这里str0str1变量引用的数组内容相同,但是绝不是同一个数组,也就是说内存中除了str2外,还有两个长度内容都相同的数组。

    注意,鼎泰初始化和动态初始化不能同时使用。

    而执行动态初始化时,程序员指定了数组的长度,即为每个数组元素指定所需的内存空间,系统负责为这些数组元素分配初始值。系统将按照如下规则分配到初始值:

    >基本类型:

           >整数类型(byte , short , int , long):数组元素的初始值为0

           >浮点类型(float , double)0.0

           >字符类型(char , string)’\u000’

           >布尔型(boolean)false

    >引用类型(类、接口和数组)null

    1)、数组变量和数组对象

    Java的数组变量是一种引用类型的变量,通常情况下被存放在栈内存中,它并不是数组本身,它只是指向堆内存中的数组对象(C语言里的指针差不多)

    数组对象是保存在堆内存中的连续内存空间。

    理解了这两个概念之后,我们可以对数组的初始化有一个更深的认识,即对数组执行初始化,其实并不是对数组变量执行初始化,而是要对数组对象执行初始化(即为该数组对象分配一块连续的内存空间)

    认识到这一点之后我们可以解释这样一种假象,即认为数组的长度是可变的,例如下面的实例:

    public class test01 {

           public static void main(String[] args) {

                  String[] str0 = new String[]{"小武灵灵" , "41009160" , "陕西师范大学"};

                  String[] str1 = new String[2];

                  str1 = str0;

                  System.out.println("str1的长度为:" + str0.length);

           }

    }

    相信大家可以自行解释这种假象,这里我就不解释啦!

           2)、基本类型数组的初始化

    基本类型数组的初始化过程为:程序直接为数组分配内存空间,再将数组元素的值存入对应的内存里。例如下面的代码块:

    String[] str;

    str = new String[]{“小武灵灵” , 41009160, “地信1”};

    注意,所有局部变量都是放在栈内存里保存的,不管其是基本类型的变量,还是引用类型的变量,都是存储在各自的方法栈区中;但引用类型变量所引用的变量(包括数组、普通Java对象)则总是存储在对内存中。

    注意,引用变量本质上只是一个指针,只要程序通过引用变量访问属性,或通过引用变量来调用方法,该引用变量将会由它所引用的对象代替。

           3)、引用类型数组的初始化

    引用类型数组的数组元素依然是引用类型的,因此数组元素里存储的还是引用,它指向另一块内存,这块内存里存储了该引用变量所引用的对象。例如:

    class Student {

           public String name;

           public int number;

           public void output() {

                  System.out.println(name + “,”+number);

    }

    }

    public class Main{

           public static void main(String[] args) {

                  Student[] stu = new Student[2];

                  System.out.println(“数组长度:” + stu.length);

           Student xiaowu = new Student();

           xiaowu.name = “小武”;

           xiaowu.number = “41009160”;

           stu[0] = xiaowu;

           //下面两行代码所输出的结果都是一样的

           stu[0].output();

           xiaowu.output();

    }

    }

    在上面的程序中,内存是这样分配的:首先引用数组变量stu[]初始化完成后,内存中开辟出了长度为二的空间用来存储student对象;对引用变量xiaowu初始化完成后,内存中开辟了出了能够存储一个student对象长度的空间,用来存储student对象;将xiaowu赋给stu[0],则在内存中数组stu[0]指向对象xiaowu

    2、数组的使用

           当数组引用变量指向一个有效的数组对象之后,程序就可以通过该数组引用变量来访问数组对象。Java语言不允许直接访问对内存中的数据,因此无法直接访问堆内存中的数组对象,程序将通过数组引用变量来访问数据。

           要对数组有一个更深刻的认识,需要理解两个关系:数组元素与变量间的关系、多维数组与变量间的关系。

           1)、数组元素与变量间的关系

                  只要在已有数据类型之后增加括号,就会产生一个新的数组类型,例如:

           >int à int[]:在int类型后增加[]即变为int[]数组类型

           >Stirng à String[]:在String类型后增加[]即变为String[]数组类型

           当程序需要多个类型相同的变量来保存程序状态时,可以考虑使用数组来保存这些变量。当一个数组初始化完成,就相当于定义了多个类型相同的变量。

           无论哪种类型的数组,其数组元素其实相当于一个普通变量,把数组类型之后的括号去掉之后得到的类型就是该数组元素的类型。

           从这个角度讲,数组元素就是变量。

           注意,这里的数组元素并不是指数组对象中的数组元素,而是指数组变量的数组变量元素。

           注意,main方法声明的变量都属于局部变量,因此它们都被保存在main方法栈中;但数组元素则作为数组对象的一部分,总是保存在堆内存中,不管它们是基本类型的数组元素,还是引用类型的数组元素。

    2)、多维数组与变量间的关系

           理解了数组元素与变量之间关系之后,如果已有的类型是int,在其后增加[]后得到一个数组类型;以int[]类型为已有类型,在其后增加[]后得到int[][]依然是数组类型;

    int[][]类型为已有类型,在其后增加[]后得到int[][][]依然是数组类型。

           从上面可以看出,所谓多维数组,其实就是数组元素依然是数组的1维数组,2维数组是数组元素是1维数组的数组,3维数组是数组元素是2维数组的数组,4维数组是数组元素是3维数组的数组……N维数组是数组元素是N-1维数组的数组。

           所以,实际上我们可以这样认为:没有多维数组,只有基本数据类型和引用数据类型。

     

    综上,数组的初始化有静态初始化和动态初始化两种;数组对象和数组变量不是同一个概念对于数组变量而言;数组元素的类型分为基本类型的数组和引用类型的数组;所有局部变量都是存放在栈内存里保存的,但引用类型变量所引用的对象则总是存储在堆内存中;一定要区分它何时只是数组变量,何时代表数组对象本身;数组元素就是变量,没有多维数组。

          

     

  • 相关阅读:
    centos7安装gitlab
    jenkins 部署k8s-jar包项目
    jenkins部署k8s项目-CICD
    pipeline
    jenkins打包
    jenkins 按角色设置管理权限
    1 jenkins的介绍和安装
    PyTables的下载和安装
    解决python报错:ImportError: No module named shutil_get_terminal_size 的方法
    nodejs安装失败
  • 原文地址:https://www.cnblogs.com/jiangu66/p/3071867.html
Copyright © 2020-2023  润新知