最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java從內存角度帶你理解數組名實質是個地址的論述

 更新時間:2022年09月22日 09:16:31   作者:碳基肥宅  
這篇文章主要介紹了Java如何從內存解析的角度理解“數組名實質是一個地址”,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習吧

本文從Java語言的角度,探討一維數組與二維數組的內存解析。

一、內存的簡化結構

下圖即為內存的簡化結構。在Java語言中,內存的存儲分配是這樣的:

棧:局部變量

堆:new出來的東西,如對象、數組等

方法區(qū):包括靜態(tài)域(static)和常量池(String的內容就存儲在這里)

內存的簡化結構

這張內存簡化圖非常重要,需要大家留有印象。

接下來我們在該圖和結論的基礎上,分步來看一維數組與二維數組的內存解析。

二、一維數組的內存解析

1. 分步解析

示例代碼

public class Test{
    public static void main(String args[]){
        int[] arr;   
        arr = new int[10];
        for ( int i=0; i<10; i++ ) {  
            arr[i] =2*i+1;
            System.out.println(arr[i]);
        }
    }
}

step1int[] arr;

此時在棧中創(chuàng)建出了變量arr:

step2 arr= new int[10];

接著使用new關鍵字,來創(chuàng)建一個一維數組。需要注意的是,基本數據類型數組在顯式賦值之前, Java會自動給它們賦默認值。由于一維數組的每個元素都是int類型,因而默認值為0.

step3 arr[i] =2*i+1;

在for循環(huán)中遍歷數組arr并為其元素賦值:

綜合起來看,內存狀態(tài)如下:

2. 綜合解析

如圖,創(chuàng)建數組并賦值的過程可以簡化成如下示意圖。

左側為棧區(qū),右側為堆區(qū)

當聲明數組 int[ ] arr時,arr屬于局部變量,在棧中創(chuàng)建。如上圖中,int[ ] arr1和String[ ] arr2的操作執(zhí)行后,在左側的棧中創(chuàng)建了變量arr1與arr2.若沒有new的操作,實際上還未給數組開辟存儲空間。

只有當通過new關鍵字創(chuàng)建數組對象后,系統才在堆中劃分相應的存儲空間,并依據數組元素的數據類型給新劃分的空間自動賦初值。如上圖中,在new int[4]后,堆區(qū)開辟了4個連續(xù)的存儲空間,并賦值為0,而new String[3]后,堆區(qū)又開辟了3個存儲空間用來存儲String類型的數據,引用類型String默認初值為null.

同時,數組的地址(即數組首元素的地址,假設為0x12ab)賦值給棧區(qū)中的變量arr1,即變量arr1中存著數組的地址,通過該地址,arr1可以輕松地在堆中找到它對應的數組。

我們通過中括號 [ ] 來訪問數組中的各個元素。我們執(zhí)行arr1[0] = 10;這一代碼時,實際便是根據棧內arr1中存著的地址,找到將堆區(qū)中的數組空間,并將第一個空間中的0改為了10.

而對于arr2[ ]數組,在new過之后又new了一次,第二次通過new String[5]開辟了一片5個存儲空間的數組。這時變量arr2中原本存著的地址0x34ab被新地址0x78cd覆蓋,arr2變量存放了新數組的地址。原數組在后續(xù)的某個時間內,將被自動回收。

當然,當棧區(qū)存有數組地址的變量arr1與變量arr2最終出棧后,在堆區(qū)劃分的數組空間也將在之后被回收。

三、二(多)維數組的內存解析

1. 綜合解析

二維數組是“數組的數組”,即一個一維數組中每個元素也是數組。由于數組既可以存儲基本數據類型,也可以存儲引用數據類型,因而“數組中存數組”的理解是可行的。

二維數組的創(chuàng)建過程與一維數組類似,這里便不再分步解析。我們直接來看內存解析圖:

二維數組的內存解析

與一維數組的不同之處在于,二維數組中外層元素也用于存儲地址。在創(chuàng)建二維數組時,除了在堆區(qū)中為外層元素(一維數組)開辟了存儲空間外,還為內層元素開辟了存儲空間。同時,內層元素的首元素地址返回給外層元素。

這樣,數組名arr1與一維數組名arr1[ ] 像橋梁一樣連接到內層元素arr1[ ][ ]。通過地址和存有地址的棧區(qū)變量arr1、堆區(qū)中的一維數組arr1[ ],我們可以輕松地訪問到內層元素。

其中,內層元素的長度可以不相等。int[ ][ ] arr = new int[ ][ ]{{1,2,3},{4,5},{6,7,8}};這樣也是可行的,從圖中就能清晰的看出,內層元素之間其實是相對獨立的。

2. 默認初始化方式對初始值的影響

針對于 int[][] arr = new int[4][3]; 這樣將內外層元素個數都指定了的初始化方式,外層元素的初始化值為地址值,內層元素的初始化值則與一維數組初始化情況相同(由元素的數據類型而決定)。

而針對 int[][] arr = new int[4][]; 這樣省略內層元素長度的初始化方式而言,外層元素的初始化值為null(相當于未賦值的引用數據類型),內層元素則根本沒有初始化值而言(空間還沒開辟),不能調用,否則編譯器將報錯。

測試

//測試代碼
public class ArrayTest {
	public static void main(String[] args) {
		int[][] arr = new int[4][3];
		System.out.println(arr[0]);	//[I@15db9742
		System.out.println(arr[0][0]);	//0
        //System.out.println(arr);
		System.out.println("***********************");
		float[][] arr1 = new float[4][3];
		System.out.println(arr1[0]);	//地址值
		System.out.println(arr1[0][0]);	//0.0
		System.out.println("***********************");
		String[][] arr2 = new String[4][2];
		System.out.println(arr2[1]);	//地址值
		System.out.println(arr2[1][1]);	//null
		System.out.println("*********************");
		double[][] arr3 = new double[4][];
		System.out.println(arr3[1]);	//null
//		System.out.println(arr3[1][0]);	//報錯
	}
}

總結

單看數組名,實際上是一個創(chuàng)建在棧區(qū)的局部變量。整個數組數據量可能較大,直接把數組內所有的元素都存放在棧區(qū)是不太妥當的。因而,數組的主體部分實際上開辟在堆區(qū)。

要想訪問數組,若堆區(qū)的內容與棧區(qū)的數組名arr之間沒有任何關系,是無法找到想要訪問的數組內容的。因而,堆區(qū)會返回開辟的數組空間首元素的地址作為數組主體的地址,傳給棧區(qū)的局部變量arr(它是一個數組名)。若是二維數組,內層元素的首元素地址會作為外層元素(也就是一維數組名)的內容。

通過地址和存儲地址的“數組名”、“一維數組名”,我們可以一連串地找到我們想要訪問的數組元素。

該部分內容我用文字表述可能不夠簡練,大家更多地可以看圖,圖為重點,通過圖示來理解內存解析更好一些。

到此這篇關于Java從內存角度帶你理解數組名實質是個地址的論述的文章就介紹到這了,更多相關Java數組名內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • 深入探究SpringBoot中的Sleuth用法

    深入探究SpringBoot中的Sleuth用法

    Sleuth是一個分布式跟蹤系統,用于跟蹤應用程序中的請求和操作,在本文中,我們將探討SpringBoot中的Sleuth是什么,以及如何使用它來跟蹤應用程序中的請求和操作,感興趣的小伙伴跟著小編一起來探討吧
    2023-07-07
  • Java?嵌入數據引擎從?SQLite?到?SPL詳解

    Java?嵌入數據引擎從?SQLite?到?SPL詳解

    這篇文章主要介紹了Java?嵌入數據引擎:從?SQLite?到?SPL,SQLite架構簡單,其核心雖然是C語言開發(fā)的,但封裝得比較好,對外呈現為一個小巧的Jar包,能方便地集成在Java應用中,本文給大家介紹的非常詳細,需要的朋友參考下
    2022-07-07
  • SpringBoot+JWT實現單點登錄完美解決方案

    SpringBoot+JWT實現單點登錄完美解決方案

    單點登錄是一種統一認證和授權機制,指在多個應用系統中,用戶只需要登錄一次就可以訪問所有相互信任的系統,不需要重新登錄驗證,這篇文章主要介紹了SpringBoot+JWT實現單點登錄解決方案,需要的朋友可以參考下
    2023-07-07
  • spring boot 測試單元修改數據庫不成功的解決

    spring boot 測試單元修改數據庫不成功的解決

    這篇文章主要介紹了spring boot 測試單元修改數據庫不成功的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-09-09
  • MyBatis中selectKey標簽及主鍵回填實現

    MyBatis中selectKey標簽及主鍵回填實現

    <selectKey>標簽在MyBatis中提供了一種靈活的方式來生成和回填主鍵,本文就來介紹一下selectKey標簽及主鍵回填實現,具有一定的參考價值,感興趣的可以了解一下
    2024-12-12
  • java如何利用poi解析doc和docx中的數據

    java如何利用poi解析doc和docx中的數據

    這篇文章主要給大家介紹了關于java如何利用poi解析doc和docx中數據的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-04-04
  • SpringCloud OpenFeign與Ribbon客戶端配置詳解

    SpringCloud OpenFeign與Ribbon客戶端配置詳解

    在springcloud中,openfeign是取代了feign作為負載均衡組件的,feign最早是netflix提供的,他是一個輕量級的支持RESTful的http服務調用框架,內置了ribbon,而ribbon可以提供負載均衡機制,因此feign可以作為一個負載均衡的遠程服務調用框架使用
    2022-11-11
  • java中Webclient對象如何解析400狀態(tài)碼詳解

    java中Webclient對象如何解析400狀態(tài)碼詳解

    這篇文章主要介紹了java中Webclient對象如何解析400狀態(tài)碼的相關資料,文中通過代碼介紹的非常詳細,對大家學習或者使用java具有一定的參考借鑒價值,需要的朋友可以參考下
    2024-12-12
  • Springboot開發(fā)之利用Docker和Kubernetes部署微服務

    Springboot開發(fā)之利用Docker和Kubernetes部署微服務

    這篇文章主要介紹了如何將Spring Boot開發(fā)的微服務通過Docker容器化,并使用Kubernetes進行部署和管理,幫助讀者掌握現代云原生應用的完整開發(fā)部署流程,有需要的可以了解下
    2025-03-03
  • 在SpringBoot中實現斷點續(xù)傳的實例代碼

    在SpringBoot中實現斷點續(xù)傳的實例代碼

    在 Spring Boot 或任何其他 web 開發(fā)框架中,斷點續(xù)傳是一種技術,允許文件的傳輸在中斷后可以從中斷點重新開始,而不是從頭開始,種技術在處理大文件或在不穩(wěn)定的網絡環(huán)境中尤為重要,本文給大家介紹了SpringBoot中實現斷點續(xù)傳的實例代碼,需要的朋友可以參考下
    2024-07-07

最新評論

吉木萨尔县| 桃源县| 敦煌市| 沅陵县| 榆林市| 丽水市| 义马市| 绩溪县| 海丰县| 滁州市| 沁阳市| 林芝县| 四子王旗| 牡丹江市| 安远县| 宣恩县| 乐至县| 泾川县| 雷州市| 惠来县| 贵德县| 兴隆县| 大安市| 工布江达县| 门头沟区| 湛江市| 灵璧县| 苍山县| 武城县| 紫阳县| 芦山县| 德州市| 岳阳市| 句容市| 连江县| 红原县| 元氏县| 广州市| 汤原县| 太保市| 盐津县|