zoukankan      html  css  js  c++  java
  • java学习之数组(一)【内存】

    在java语言当中,为了更方便多个数据的管理,这里提供数组。

    比如说,现在我们有一组数据,7,8,9,9,为了保存这四个数据,我们分别要定义变量来保存,少了还好说。但是假如,有100多个数据呢,我们一个一个定义起来,岂不是很麻烦。这个时候我们就引入了数组这个概念,来方便我们对多个数组的管理。

    数组的定义:同一种类型数据的集合,通俗来讲,数组就是一个容器,容纳同类型的数据。

    数组的书写格式:元素类型[]  数组名 = new 元素类型[元素的个数或者叫做数组的格式]。

    class ArrDemo{
    
    	public static void main(String[] args) {
    		/**
    		*数组的定义格式:元素类型[] = new 元素类型[数组的长度或者叫做元素的个数];
    		*我们知道数组是存放许多同类型的元素的实体,之所以叫做实体是因为他是实实在在存放数据的地方。那么我们为了能区别于其他的变量声明,这里我们
    		*用一个关键字来创建他,这个关键字就是new。那么之后的int[]是表示建立一个int类型的数组,其中的数字7就是这个数组的长度
    		*数组的一个特点就是,一旦你定义了一个数组,你就必须明确他的长度。
    		*/
    
    		int[] arr = new int[7];
    
    		/**
    		*在定义完数组之后,我们就开始访问他,这个时候数组提供给我们的就是一个索引,表示我们要去的数据的位置。
    		*数组的索引的特点就是都是从0开始的,并且在你没有初始值的时候,他们都有各自类型的默认值。
    		*
    		*byte,short,int类型的默认值是0
    		*float类型的默认值是0.0f
    		*double类型的默认值是0.0
    		*char类型的默认值比较特殊,他的默认类型是'u0000';这里可能有一个疑问,char当中不是只能容纳一个字符么,为什么这里可以容纳五个。因为这里容纳的
    		*并不是字符,而是字符的unicode编码,以u 开头的就是unicode编码,表示的意思是空字符。
    		*
    		*/
    
    		System.out.println(arr[0]);//这里打印出来的就是int类型的默认值0;
    		
    
    	}
    
    }
    

      这里我们也可以通过索引对数组中元素进行赋值,比如;arr[0] = 89;这样就把索引为0位置的数字,改为了89这个整数。

    为了更好的理解数组,我们来看一下数组在内存当中的表现。

    当我们运行一个程序的时候,我们需要在内存当中单独开辟一个内存空间,同时这个被分配的内存又有一个进一步的更细致的内存划分。因为这个内存划分就跟一个操场的划分差不多,有足球场,篮球场,田径区等等,这样划分的目的是为了让各个区域独立开,更高效的利用内存。如果一个操场,什么都有,一个是太乱不容易管理,一个是不安全容易出事。那么内存到底划分为哪些部分呢?

    内存的划分:

      1、寄存器,这个我们用不着,这个都是cpu直接操作的。

      2、本地方法区。//这个是跟所处的系统相关的,因操作系统不一样

      3、方法去。//内加载机制

      4、栈存储区。

      5、堆存储区域。

    栈内存:

      里边存储的是什么?

        存储的都是局部变量。所谓的局部变量就是凡是定义在方法当中的变量都是局部变量。在类当中直接存储的就不是局部变量。

        该局部变量所属的作用域一旦结束,那么这个局部变量也随之被内存自动释放。

      特点:栈内存更新速度很块,声明周期很短。

        

    class MemDemo{
    	
    
    	int a  = 20;//这个没有定义在方法当中,这个就不是局部变量
         {
           int c = 8777;//在局部代码块当中定义的变量也是局部变量,限定局部变量的声明周期。当我们使用一大部分变量的时候,有些变量用完之后,就释放了,这部分可以利用这种结构。
         }   public static void main(String[] args) { int b = 89;//这个就是定义在方法当中的,所以他是局部变量 //byte[] bt = new byte[9]; //short[] sr= new short[9]; //System.out.println(bt[0]); //System.out.println(sr[0]);          for(int x=5;x<9;x++)//这里面的x也是局部变量 } }

      堆内存:

        堆内存存储的是什么呢?

          堆内存当中存储的是数组和对象(其实数组就是对象的意思)。凡是new关键字建立的都在堆当中。数组和对象都是实体,实体的就是实实在在存储的个数。实体用于封装数据,而且都封装数字。实体当中存储这个一堆数据,其中一个数据消亡了,那么其他的数据都还可以用的。那么此时这个实体肯定是不能随时释放的。

          堆不会随时释放,

        特点:

          1、每一个实体都有一个唯一的地址值。

          2.堆内存中的每一个变量都有默认初始化的值,根据的类型的不同而不同。

          3、垃圾回收机制。

    方法先进栈,然后变量才进栈。当我们把数组实体赋值给一个栈内的变量的时候,其实就是在堆内存开辟了一个内存空间,并且给她分配了一个内存地址,此时地址虽然是二进制,但是为了表示方便采用大进制的来存储,即十六进制。这个时候数组就有一个唯一的地址。在我们定义数组的时候,我们定义了元素的个数,那么数组实体当中就为这些个元素分配了一个唯一的索引。当我们在堆内存当中定义一个数组实体之后,他会进行一次默认的初始化。这个就是一个规定。堆内存的变量有个特点,就会有一个默认初始化。

    那么当把堆内存当中的实体付给栈内存当中的变量时,实际上是把堆内存当中的变量地址,赋值给栈内存的变量。栈内存当中的变量通过操作堆内存的地址,来操作数据。这个种方式就叫做引用。

    当我们给数组赋值的时候,一定要考虑到类型是否相同。

    class MemDemo{
    	
    
    	public static void main(String[] args) {
    
    		int[] a =  new int[9];
    		a[0] = 's';//非法的数据类型不一样
    		a[0] = null;//非法的数据类型不一样
    		a = null;//null 的一个作用在与 解索引,即栈内存当中变量与堆内存当中的变量分开。
    
    	}
    
    }
    

    当堆内存当中没有被栈内存当中的变量引用时,此时就变成了垃圾。会被GC不定时回收掉,以免内存占满,系统崩溃掉。

    内存图:

    数组操作的时候,出现的小错误:

    1、不能超出索引范围。

      

    class MemDemo{
    	
    
    	public static void main(String[] args) {
    
    		int[] a =  new int[3];
    
    		System.out.println(a[3]);
    
    	}
    
    }
    

     此时我们编译的时候,没有报错,但是我们明明知道他是错误的。我们编译的时候,并没有分配内存。 比如说假如我们编译完了就分配内存了,那么如果我们编译完了放在那里,并没有运行,此时如果分配的话,显示不合理,也不合逻辑。

     编译的过程是检查是否有语法的错误,但是在这里我们的语法并没有错误。因为a[3]的这个索引只有程序运行的时候,才会去找。此时我们再用JVM来运行,此时它创建完数组之后,来找这个内存的时候发现并没有找到,所以报错:连位置都详细告诉我们了。

    假如我们这样:

    class MemDemo{
    	
    
    	public static void main(String[] args) {
    
    		int[] a =  new int[3];
    	
    		a = null;
    
    		System.out.println(a[0]);
    
    
    	}
    
    }
    

      

    当引用型变量即数组或者对象,在没有任何实体指向的情况下被调用,还在用他操作实体,此时就会报空指针错误。

    如果我们直接打印数组,会出现什么呢?

    class MemDemo{
    	
    
    	public static void main(String[] args) {
    
    		int[] a =  new int[3];
    	
    		//a = null;
    
    		System.out.println(a);
    
    
    	}
    
    }
    

      运行结果:

    这个字符什么意思呢?

    我们分开看:

    1、"["这个符号代表是数组。

    2、"I"这个代表是int类型

    3、@分界线,左边是需要看懂的。

    4、15bdc50这个是数组实体的哈希值,是一个算法(如果冲突就继续往下算,这个哈希算法是采用windows的,根据系统自己定义的),用这个算法计算,数组实体在内存当中的存储位置。

    未完待续。

  • 相关阅读:
    自己上手写性能测试工具(一)
    你的领导真的很傻X吗?
    微软自动化测试工具palywright
    虫师『性能测试』文章大汇总
    虫师『软件测试』基础 与 测试杂谈
    「UI 测试自动化selenium」汇总
    web测试02
    web测试01
    测试20
    测试19
  • 原文地址:https://www.cnblogs.com/sunchuanzhen/p/3321743.html
Copyright © 2011-2022 走看看