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

Java從內(nèi)存角度帶你理解數(shù)組名實(shí)質(zhì)是個(gè)地址的論述

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

本文從Java語(yǔ)言的角度,探討一維數(shù)組與二維數(shù)組的內(nèi)存解析。

一、內(nèi)存的簡(jiǎn)化結(jié)構(gòu)

下圖即為內(nèi)存的簡(jiǎn)化結(jié)構(gòu)。在Java語(yǔ)言中,內(nèi)存的存儲(chǔ)分配是這樣的:

棧:局部變量

堆:new出來(lái)的東西,如對(duì)象、數(shù)組等

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

內(nèi)存的簡(jiǎn)化結(jié)構(gòu)

這張內(nèi)存簡(jiǎn)化圖非常重要,需要大家留有印象。

接下來(lái)我們?cè)谠搱D和結(jié)論的基礎(chǔ)上,分步來(lái)看一維數(shù)組與二維數(shù)組的內(nèi)存解析。

二、一維數(shù)組的內(nèi)存解析

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;

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

step2 arr= new int[10];

接著使用new關(guān)鍵字,來(lái)創(chuàng)建一個(gè)一維數(shù)組。需要注意的是,基本數(shù)據(jù)類型數(shù)組在顯式賦值之前, Java會(huì)自動(dòng)給它們賦默認(rèn)值。由于一維數(shù)組的每個(gè)元素都是int類型,因而默認(rèn)值為0.

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

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

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

2. 綜合解析

如圖,創(chuàng)建數(shù)組并賦值的過(guò)程可以簡(jiǎn)化成如下示意圖。

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

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

只有當(dāng)通過(guò)new關(guān)鍵字創(chuàng)建數(shù)組對(duì)象后,系統(tǒng)才在堆中劃分相應(yīng)的存儲(chǔ)空間,并依據(jù)數(shù)組元素的數(shù)據(jù)類型給新劃分的空間自動(dòng)賦初值。如上圖中,在new int[4]后,堆區(qū)開(kāi)辟了4個(gè)連續(xù)的存儲(chǔ)空間,并賦值為0,而new String[3]后,堆區(qū)又開(kāi)辟了3個(gè)存儲(chǔ)空間用來(lái)存儲(chǔ)String類型的數(shù)據(jù),引用類型String默認(rèn)初值為null.

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

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

而對(duì)于arr2[ ]數(shù)組,在new過(guò)之后又new了一次,第二次通過(guò)new String[5]開(kāi)辟了一片5個(gè)存儲(chǔ)空間的數(shù)組。這時(shí)變量arr2中原本存著的地址0x34ab被新地址0x78cd覆蓋,arr2變量存放了新數(shù)組的地址。原數(shù)組在后續(xù)的某個(gè)時(shí)間內(nèi),將被自動(dòng)回收。

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

三、二(多)維數(shù)組的內(nèi)存解析

1. 綜合解析

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

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

二維數(shù)組的內(nèi)存解析

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

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

其中,內(nèi)層元素的長(zhǎng)度可以不相等。int[ ][ ] arr = new int[ ][ ]{{1,2,3},{4,5},{6,7,8}};這樣也是可行的,從圖中就能清晰的看出,內(nèi)層元素之間其實(shí)是相對(duì)獨(dú)立的。

2. 默認(rèn)初始化方式對(duì)初始值的影響

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

而針對(duì) int[][] arr = new int[4][]; 這樣省略內(nèi)層元素長(zhǎng)度的初始化方式而言,外層元素的初始化值為null(相當(dāng)于未賦值的引用數(shù)據(jù)類型),內(nèi)層元素則根本沒(méi)有初始化值而言(空間還沒(méi)開(kāi)辟),不能調(diào)用,否則編譯器將報(bào)錯(cuò)。

測(cè)試

//測(cè)試代碼
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]);	//報(bào)錯(cuò)
	}
}

總結(jié)

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

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

通過(guò)地址和存儲(chǔ)地址的“數(shù)組名”、“一維數(shù)組名”,我們可以一連串地找到我們想要訪問(wèn)的數(shù)組元素。

該部分內(nèi)容我用文字表述可能不夠簡(jiǎn)練,大家更多地可以看圖,圖為重點(diǎn),通過(guò)圖示來(lái)理解內(nèi)存解析更好一些。

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

相關(guān)文章

  • 深入探究SpringBoot中的Sleuth用法

    深入探究SpringBoot中的Sleuth用法

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

    Java?嵌入數(shù)據(jù)引擎從?SQLite?到?SPL詳解

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

    SpringBoot+JWT實(shí)現(xiàn)單點(diǎn)登錄完美解決方案

    單點(diǎn)登錄是一種統(tǒng)一認(rèn)證和授權(quán)機(jī)制,指在多個(gè)應(yīng)用系統(tǒng)中,用戶只需要登錄一次就可以訪問(wèn)所有相互信任的系統(tǒng),不需要重新登錄驗(yàn)證,這篇文章主要介紹了SpringBoot+JWT實(shí)現(xiàn)單點(diǎn)登錄解決方案,需要的朋友可以參考下
    2023-07-07
  • spring boot 測(cè)試單元修改數(shù)據(jù)庫(kù)不成功的解決

    spring boot 測(cè)試單元修改數(shù)據(jù)庫(kù)不成功的解決

    這篇文章主要介紹了spring boot 測(cè)試單元修改數(shù)據(jù)庫(kù)不成功的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-09-09
  • MyBatis中selectKey標(biāo)簽及主鍵回填實(shí)現(xiàn)

    MyBatis中selectKey標(biāo)簽及主鍵回填實(shí)現(xiàn)

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

    java如何利用poi解析doc和docx中的數(shù)據(jù)

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

    SpringCloud OpenFeign與Ribbon客戶端配置詳解

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

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

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

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

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

    在SpringBoot中實(shí)現(xiàn)斷點(diǎn)續(xù)傳的實(shí)例代碼

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

最新評(píng)論

北碚区| 广南县| 望都县| 石阡县| 萝北县| 固原市| 湄潭县| 福州市| 黎城县| 东城区| 攀枝花市| 南充市| 通化县| 富民县| 敦化市| 巧家县| 留坝县| 东宁县| 新丰县| 介休市| 旺苍县| 陇南市| 澳门| 平昌县| 阿城市| 南开区| 萝北县| 达日县| 泾川县| 四子王旗| 昭觉县| 灌阳县| 芒康县| 灵川县| 新绛县| 扶绥县| 永福县| 温泉县| 康马县| 汶川县| 巴里|