溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Java數(shù)組與堆棧分別是什么

發(fā)布時間:2021-06-29 14:35:30 來源:億速云 閱讀:122 作者:chen 欄目:開發(fā)技術(shù)

本篇內(nèi)容介紹了“Java數(shù)組與堆棧分別是什么”的有關(guān)知識,在實(shí)際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!

一、數(shù)組創(chuàng)建

1.1 聲明并賦值

int[] a = {1,2,3};

1.2 聲明數(shù)組名開辟空間并且賦值

int[] a;
a = new int[]{1,2,3};

1.3 聲明數(shù)組時指定元素個數(shù)然后賦值

int[] a= new int[3];

這里Java會默認(rèn)數(shù)組元素值為0

1.4 在以上的基礎(chǔ)上創(chuàng)建多維數(shù)組

int[][] a = {{1,2,3},{4,5,6},{7,8,9}}; //每個子數(shù)組元素個數(shù)不要求均相同
int[][] a = new int[m][n]; //其中n可以省略,在創(chuàng)建的時候可以指定
int[][][] a = new int[m][n][q]; //同樣其中n、q可以省略

同樣的,在new一個數(shù)組時,如不初始化,Java會默認(rèn)數(shù)組元素值為0。

二、數(shù)據(jù)類型

Java中的數(shù)據(jù)類型有兩種:

2.1 八種基本數(shù)據(jù)類型

  • int

  • short

  • long

  • byte

  • float

  • double

  • boolean

  • char

這種類型的定義是通過諸如int a = 3; long b = 255L;的形式來定義的,稱為自動變量。
自動變量存的是字面值,這些字面值固定定義在某個程序塊里面,程序塊退出后,字段值就消失了,出于追求速度的原因,就存在于棧中。

2.2 包裝類數(shù)據(jù)

包裝類的數(shù)據(jù)是如 Integer, String, Double等將相應(yīng)的基本數(shù)據(jù)類型包裝起來的類。這些類數(shù)據(jù)全部存在于堆中,Java用new()語句來顯式地告訴編譯器,在運(yùn)行時才根據(jù)需要動態(tài)創(chuàng)建,因此比較靈活,但缺點(diǎn)是要占用更多的時間。
String是一個特殊的包裝類數(shù)據(jù)。即可以用String str = "abc";的形式來創(chuàng)建,也可以用String str = new String("abc");的形式來創(chuàng)建。String str = "abc";中,并沒有通過new()來創(chuàng)建實(shí)例,因?yàn)?code>String str = "abc"; 是存儲在字符串常量池中。 字符串常量池則存在于方法區(qū)。
JVM為了提高性能和減少內(nèi)存開銷,在實(shí)例化字符串常量的時候進(jìn)行了一些優(yōu)化。

1.為字符串開辟一個字符串常量池,類似于緩存區(qū)。

2.創(chuàng)建字符串常量時,首先堅(jiān)持字符串常量池是否存在該字符串。存在該字符串,

3.返回引用實(shí)例,不存在,實(shí)例化該字符串并放入池中。

String str1 = "abc"; 
String str2 = "abc";
System.out.println(str1==str2); //true

可以看到結(jié)果是true,結(jié)果說明,JVM創(chuàng)建了兩個引用str1和str2,但只創(chuàng)建了一個對象,而且兩個引用都指向了這個對象。

String str1 = "abc";
String str2 = "abc";
str1 = "bcd";
System.out.println(str1 + "," + str2); //bcd, abc
System.out.println(str1==str2); //false

參考上面的代碼可以知道,賦值的變化導(dǎo)致了類對象引用的變化,str1指向了另外一個新對象!而str2仍舊指向原來的對象。上例中,當(dāng)我們將str1的值改為"bcd"時,JVM發(fā)現(xiàn)在棧中沒有存放該值的地址,便開辟了這個地址,并創(chuàng)建了一個新的對象,其字符串的值指向這個地址。
事實(shí)上,String類被設(shè)計(jì)成為不可改變(immutable)的類。如果你要改變其值,可以,但JVM在運(yùn)行時根據(jù)新值悄悄創(chuàng)建了一個新對象,然后將這個對象的地址返回給原來類的引用。這個創(chuàng)建過程雖說是完全自動進(jìn)行的,但它畢竟占用了更多的時間。在對時間要求比較敏感的環(huán)境中,會帶有一定的不良影響。
因此,并沒有與String是不可變的相矛盾。
繼續(xù)修改代碼:

String str1 = "abc";
String str2 = "abc";
str1 = "bcd";
String str3 = str1;
System.out.println(str3); //bcd
String str4 = "bcd";
System.out.println(str1 == str4); //true

可以看出,str3 這個對象的引用直接指向str1所指向的對象(注意,str3并沒有創(chuàng)建新對象)。當(dāng)str1改完其值后,再創(chuàng)建一個String的引用str4,并指向因str1修改值而創(chuàng)建的新的對象。可以發(fā)現(xiàn),這回str4也沒有創(chuàng)建新的對象,從而再次實(shí)現(xiàn)棧中數(shù)據(jù)的共享。
繼續(xù)修改代碼:

String str1 = new String("abc");
String str2 = "abc";
System.out.println(str1==str2); //false

可以發(fā)現(xiàn)此時返回false,這是因?yàn)橥ㄟ^new出來的放在了中,而第二個存于棧中,所以不相等。
另外:數(shù)據(jù)類型包裝類的值不可修改。不僅僅是String類的值不可修改,所有的數(shù)據(jù)類型包裝類都不能更改其內(nèi)部的值。

三、棧、棧、方法區(qū)

是一種連續(xù)儲存的數(shù)據(jù)結(jié)構(gòu),具有先進(jìn)后出的性質(zhì)。
是一種非連續(xù)的樹形儲存數(shù)據(jù)結(jié)構(gòu),每個節(jié)點(diǎn)有一個值,整棵樹是經(jīng)過排序的。特點(diǎn)是根結(jié)點(diǎn)的值最小(或最大),且根結(jié)點(diǎn)的兩個子樹也是一個堆。常用來實(shí)現(xiàn)優(yōu)先隊(duì)列,存取隨意。
(stack)與(heap)都是Java用來在Ram中存放數(shù)據(jù)的地方。與C++不同,Java自動管理?xiàng):投?,程序員不能直接地設(shè)置?;蚨?。

3.1 棧

1.每個線程包含一個棧區(qū),棧中只保存基礎(chǔ)數(shù)據(jù)類型的對象和自定義對象的引用(不是對象)。

2.每個棧中的數(shù)據(jù)(原始類型和對象引用)都是私有的。

3.棧分為3個部分:基本類型變量區(qū)、執(zhí)行環(huán)境上下文、操作指令區(qū)(存放操作指令)

4.數(shù)據(jù)大小和生命周期是可以確定的,當(dāng)沒有引用指向數(shù)據(jù)時,這個數(shù)據(jù)就會自動消失。

通常的操作有入棧(壓棧),出棧和棧頂元素。想要讀取棧中的某個元素,就是將其之間的所有元素出棧才能完成。

棧的優(yōu)勢是,存取速度比堆要快,僅次于直接位于CPU中的寄存器。但缺點(diǎn)是,存在棧中的數(shù)據(jù)大小與生存期必須是確定的,缺乏靈活性。
另外,棧數(shù)據(jù)可以共享
類似于int a = 3;等都是存放于棧中,當(dāng)新創(chuàng)建值時Java會判斷棧中是否已存在,若存在則引用該地址,不存在則創(chuàng)建。例如:

 int a = 3; int b = 3;

編譯器先處理int a = 3;首先它會在棧中創(chuàng)建一個變量為a的引用,然后查找有沒有字面值為3的地址,沒找到,就開辟一個存放3這個字面值的地址,然后將a指向3的地址。接著處理int b = 3;在創(chuàng)建完b的引用變量后,由于在棧中已經(jīng)有3這個字面值,便將b直接指向3的地址。這樣,就出現(xiàn)了a與b同時均指向3的情況。
特別注意的是,這種字面值的引用與類對象的引用不同。假定兩個類對象的引用同時指向一個對象,如果一個對象引用變量修改了這個對象的內(nèi)部狀態(tài),那么另一個對象引用變量也即刻反映出這個變化。相反,通過字面值的引用來修改其值,不會導(dǎo)致另一個指向此字面值的引用的值也跟著改變的情況。如上例,我們定義完a與 b的值后,再令a=4;那么,b不會等于4,還是等于3。在編譯器內(nèi)部,遇到a=4;時,它就會重新搜索棧中是否有4的字面值,如果沒有,重新開辟地址存放4的值;如果已經(jīng)有了,則直接將a指向這個地址。因此a值的改變不會影響到b的值。

3.2 堆

的優(yōu)勢是可以動態(tài)地分配內(nèi)存大小,生存期也不必事先告訴編譯器,Java的垃圾收集器會自動收走這些不再使用的數(shù)據(jù)。但缺點(diǎn)是,由于要在運(yùn)行時動態(tài)分配內(nèi)存,存取速度較慢。

1.存儲的是對象,每個對象都包含一個與之對應(yīng)的class。

2.JVM只有一個堆區(qū)(heap)被所有線程共享,堆中不存放基本類型和對象引用,只存放對象本身。

3.對象的由垃圾回收器負(fù)責(zé)回收,因此大小和生命周期不需要確定。

3.3 方法區(qū)

1.靜態(tài)區(qū),跟堆一樣,被所有的線程共享。

2.方法區(qū)中包含的都是在整個程序中永遠(yuǎn)唯一的元素,如class,static變量

字符串常量池則存在于方法區(qū)

Java數(shù)組與堆棧分別是什么 字

符串對象的創(chuàng)建 面試題

面試題:String str4 = new String(“abc”) 創(chuàng)建多少個對象?

1、在常量池中查找是否有“abc”對象。

1)有則返回對應(yīng)的引用實(shí)例;

2)沒有則創(chuàng)建對應(yīng)的實(shí)例對象。

2、在堆中 new 一個 String(“abc”) 對象。

3、將對象地址賦值給str4,創(chuàng)建一個引用。

所以,常量池中沒有“abc”字面量則創(chuàng)建兩個對象,否則創(chuàng)建一個對象,以及創(chuàng)建一個引用。

“Java數(shù)組與堆棧分別是什么”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識可以關(guān)注億速云網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI