Java 中數組的內存分配


Java 中數組的內存分配

1、Java 程序在運行時,需要在內存中分配空間。為了提高運算效率,就對空間進行了不同區域的划分,因為每一片區域都有特定的處理數據和內存管理方式。

2、數組基本概念

	數組是存儲同一種數據類型多個元素的容器。
	數組既可以存儲基本數據類型,也可以存儲引用數據類型。
	
	格式:數據類型[] 數組名 ;
		  int[] arr;

	數組的初始化方式:

		動態初始化 : 初始化時只指定數組長度,由系統為數組分配初始值。
		格式:數據類型[] 數組名 = new 數據類型[數組長度];
		             數組長度其實就是數組中元素的個數。
			 int[] arr = new int[3];
		解釋:定義了一個int類型的數組,這個數組中可以存放3個int類型的值。
		
		靜態初始化:初始化時指定每個數組元素的初始值,由系統決定數組長度
		格式:數據類型[] 數組名 = new 數據類型[]{元素1,元素2,...};
			  int[] arr = {1,2,3};
		解釋:定義了一個int類型的數組,並且存進去{1,2,3}三個數。

3、Java中數組的內存分配

A、基本內存分配概念圖解

	int[] arr 存在於堆內存,new int[3] 存在於棧內存。

	在堆內存中每一個 new 出來的對象都有一個唯一的地址值,就如同圖中的 001,在 int[] arr = new int[3]; 
	相當於把堆內存的地址值 001 賦值給棧內存的的數組。當執行打印語句時候 : System.out.println(arr); 會打印出地址值。
	
	堆內存每一個對象的數據類型都有默認值(在沒有賦值的情況下),如圖所示,
	當執行打印語句時候 : System.out.println(arr[0]); 會打印出0。
	當執行打印語句時候 : System.out.println(arr[1]); 會打印出0。
	當執行打印語句時候 : System.out.println(arr[2]); 會打印出0。
	棧內存通過地址值 001 找到堆內存對應的 001 地址值,然后通過索引找到對應的數值。

B、靜態初始化內存圖解

	靜態初始化內存如圖:當數組初始化的時候,都會有默認值,但是因為我們初始化的時候進行了賦值,所以默認值會被新的賦值所覆蓋。

C、一個數組的內存圖

	如圖所示,初始值都是 0,當給數組元素賦值時,arr[0]、arr[2] 通過地址值找到堆中對應的地址值,將 arr[0]、arr[2] 進行重新賦值。

D、兩個數組的內存圖

	如圖所示,定義了 2 個數組 arr、arr2,它們的初始化都是在堆內存中開辟空間,進行初始化的原始賦值。然后通過不同的地址值地址給不同的的數組進行賦值。

E、兩個數組指向同一個地址的內存圖(重點)

	如圖所示,初始化數組 arr,然后進行賦值操作。輸出即為:100、200、300。
			 當定義數組 arr2 的時候把第一個數組 arr 的地址值賦給第二個數組,arr2 數組會根據地址值找到堆內存中的 arr 的地址及,
			 然后給第二個數組進行賦值,會將原來 arr 的數值進行覆蓋,所以當我們再次打印 arr 和 arr2 的數據時候,會出現一樣的數據。

F、數組操作的兩個常見小問題:空指針和索引越界

	索引越界:如圖所以,數組的初始化是從 0 開始,所以訪問數組元素 arr[3] 的時候,會出項索引越界異常。
	空指針:如圖所示,將 null 賦值給 arr,相當於地址001就沒有了,既然沒有了地址值指向堆內存,所以就會出項空指針異常。

G、對象數組的內存圖

		首先方法區會有 Student.class(里面有成員變量、構造方法、成員方法)、StudentDemo.class(里面有 main函數)。
		main 方法執行,棧中開辟空間創建 Student[ ] students,堆內存中會 new Student[3] ,默認值都是 null,通過地址值
		001 指向棧。
		然后創建學生對象 Student s1,同樣通過地址值002指向堆內存為002的對象,而對象的方法(包括構造方法和成員方法)也有
		地址值 0001,堆內存通過地址值 0001 指向 方法區對象的方法 0001,進行賦值覆蓋。
		
		Student s2,Student s3同理。此時創建完對象並賦值完成時,這3個對象還和 students 數組沒有關聯。
		
		最后把學生對象作為元素賦值給學生數組:students[0]=s1,其實就是拿着 s1 的地址值 002 指向數組的第一個元素,數組
		中的 null 就被 002替代。students[1]=s2;students[2]=s;同理可得!!
		
		賦值完畢后,進行遍歷操作時,如果使用 System.out.println(s); 打印出來的是地址值001、002、003。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM