❶ java堆棧問題
void push(int item),這個item是你壓棧時需要放進棧的數據呀。stck[++tos]=item這句話就是把棧頂位置向上一個,然後把數據壓棧的過程。如果沒有item這個參數,那你把什麼壓棧呀?相反的pop彈棧過程是不需要參數的,因為彈出的數據是你棧頂的數據。
-1到9確實是超過10了,但是棧頂位置可以是-1,這代表棧是空的,當tos為0時,已經代表棧中有一個元素了。
❷ java中的堆棧詳解
簡單的說 其實 棧 就是存放變數引用的一個地方, 堆 就是存放實際對象的地方 也就是.
比如: int i = 7; 這個 其實是存在棧里邊的。內容為 i = 7。
Apple app = new Apple(); 這個 app 是在棧里邊的 他對應的是一個內存地址也在堆里邊, 而這個內存地址對應的是堆里邊存放 Apple 實例的地址。
String s = "Hello World!"; 這個其實是存在另外一塊靜態代碼區。
總體來說: 棧--主要存放引用 和基本數據類型。
堆--用來存放 new 出來的對象實例。
❸ java堆棧問題~~~
堆棧是一種數據結構,特點是堆棧中的數據先進後出,或者說後進先出。你可以想像堆棧是個子彈夾,先壓入的子彈放在彈夾下面,後壓入的子彈會在彈夾的上面,打槍或者卸子彈的時候先出上面的子彈,下面的子彈才能出來。
堆棧會有一個量來標識棧頂,也就是標識出堆棧里最後放進去的數據在什麼位置。堆棧可以進行的操作最基本的是兩個:一個進棧(push)一個出棧(pop),也有叫壓入彈出的。進棧的時候要判斷棧是否已滿,已滿的堆棧不能進棧,彈夾滿了,子彈肯定壓不進去了。出棧的時候要判斷棧是否為空,彈夾空了要卸子彈肯定是卸不出來的。
❹ 關於JAVA堆棧
Java中堆棧的概念當然是邏輯上的,在完全符合Java規范的Java處理器面世之前,所有Java虛擬機提供的內容都是由軟體模擬出來的。
什麼叫堆?你用十幾個麻將牌豎直疊成一摞這叫堆,你可以從上面、下面、中間任意抽出一張牌,也可以任意插入一張。
什麼叫棧?AK-47的彈匣就是一個棧,在上面的子彈沒被取出之前,你無法取出下面的子彈——盡管你可以從邊上的透明部分讀出裡面裝的是什麼型號、顏色的子彈。
堆很靈活,但是不安全。對於對象,我們要動態地創建、銷毀,不能說後創建的對象沒有銷毀,先前創建的對象就不能銷毀,那樣的話我們的程序就寸步難行,所以Java中用堆來存儲對象。而一旦堆中的對象被銷毀,我們繼續引用這個對象的話,就會出現著名的 NullPointerException,這就是堆的缺點——錯誤的引用邏輯只有在運行時才會被發現。
棧不靈活,但是很嚴格,是安全的,易於管理。因為只要上面的引用沒有銷毀,下面引用就一定還在,所以,在棧中,上面引用永遠可以通過下面引用來查找對象,同時如果確認某一區間的內容會一起存在、一起銷毀,也可以上下互相引用。在大部分程序中,都是先定義的變數、引用先進棧,後定義的後進棧,同時,區塊內部的變數、引用在進入區塊時壓棧,區塊結束時出棧,理解了這種機制,我們就可以很方便地理解各種編程語言的作用域的概念了,同時這也是棧的優點——錯誤的引用邏輯在編譯時就可以被發現。
在Java中,引用可以理解為一個永遠指向對象的指針,Java沒有指向指針的指針。
關於堆棧的資料幾乎每個講數據結構的書上都有,而至於Java中堆、棧的具體機制你可以參考一些關於Java虛擬機原理的書,不過這個好像比較難理解,我是沒指望理解的了。
以上都是我的個人觀點,僅供參考。
❺ java中堆和堆棧有什麼區別
java中堆(heap)和堆棧(stack)有什麼區別 stack 和 heep 都是內存的一部分
stack 空間小,速度比較快, 用來放對象的引用
heep 大,一般所有創建的對象都放在這里。
棧(stack):是一個先進後出的數據結構,通常用於保存方法(函數)中的參數,局部變數.
在java中,所有基本類型和引用類型都在棧中存儲.棧中數據的生存空間一般在當前scopes內(就是由{...}括起來的區域).
堆(heap):是一個可動態申請的內存空間(其記錄空閑內存空間的鏈表由操作系統維護),C中的malloc語句所產生的內存空間就在堆中.
在java中,所有使用new xxx()構造出來的對象都在堆中存儲,當垃圾回收器檢測到某對象未被引用,則自動銷毀該對象.所以,理論上說java中對象的生存空間是沒有限制的,只要有引用類型指向它,則它就可以在任意地方被使用.
1. 棧(stack)與堆(heap)都是Java用來在Ram中存放數據的地方。與C++不同,Java自動管理棧和堆,程序員不能直接地設置棧或堆。
2. 棧的優勢是,存取速度比堆要快,僅次於直接位於CPU中的寄存器。但缺點是,存在棧中的數據大小與生存期必須是確定的,缺乏靈活性。另外,棧數據可以共享,詳見第3點。堆的優勢是可以動態地分配內存大小,生存期也不必事先告訴編譯器,Java的垃圾收集器會自動收走這些不再使用的數據。但缺點是,由於要在運行時動態分配內存,存取速度較慢。
3. Java中的數據類型有兩種。
一種是基本類型(primitive types), 共有8種,即int, short, long, byte, float, double, boolean, char(注意,並沒有string的基本類型)。 這種類型的定義是通過諸如int a = 3; long b = 255L;的形式來定義的,稱為自動變數。值得注意的是,自動變數存的是字面值,不是類的實例,即不是類的引用,這里並沒有類的存在。如int a = 3; 這里的a是一個指向int類型的引用,指向3這個字面值。這些字面值的數據,由於大小可知,生存期可知(這些字面值固定定義在某個程序塊裡面,程序塊退出後,欄位值就消失了),出於追求速度的原因,就存在於棧中。
另外,棧有一個很重要的特殊性,就是存在棧中的數據可以共享。假設我們同時定義:
int a = 3;
int b = 3;
編譯器先處理int a = 3;首先它會在棧中創建一個變數為a的引用,然後查找有沒有字面值為3的地址,沒找到,就開辟一個存放3這個字面值的地址,然後將a指向3的地址。接著處理int b = 3;在創建完b的引用變數後,由於在棧中已經有3這個字面值,便將b直接指向3的地址。
這樣,就出現了a與b同時均指向3的情況。特別注意的是,這種字面值的引用與類對象的引用不同。
假定兩個類對象的引用同時指向一個對象,如果一個對象引用變數修改了這個對象的內部狀態,那麼另一個對象引用變數也即刻反映出這個變化。
相反,通過字面值的引用來修改其值,不會導致另一個指向此字面值的引用的值也跟著改變的情況。 如上例,我們定義完a與b的值後,再令a=4;那麼,b不會等於4,還是等於3。在編譯器內部,遇到a=4;時,它就會重新搜索棧中是否有4的字面值,如果沒有,重新開闢地址存放4的值;如果已經有了,則直接將a指向這個地址。因此a值的改變不會影響到b的值。
另一種是包裝類數據,如Integer, String, Double等將相應的基本數據類型包裝起來的類。這些類數據全部存在於堆中,Java用new()語句來顯示地告訴編譯器,在運行時才根據需要動態創建,因此比較靈活,但缺點是要佔用更多的時間。
4.String是一個特殊的包裝類數據。即可以用String str = new String("abc");的形式來創建,也可以用String str = "abc";的形式來創建(作為對比,在JDK 5.0之前,你從未見過Integer i = 3;的表達式,因為類與字面值是不能通用的,除了String。而在JDK 5.0中,這種表達式是可以的!因為編譯器在後台進行Integer i = new Integer(3)的轉換!)。
前者是規范的類的創建過程,即在Java中,一切都是對象,而對象是類的實例,全部通過new()的形式來創建。Java中的有些類,如DateFormat類,可以通過該類的getInstance()方法來返回一個新創建的類,似乎違反了此原則。其實不然。該類運用了單例模式來返回類的實例,只不過這個實例是在該類內部通過new()來創建的,而getInstance()向外部隱藏了此細節。那為什麼在String str = "abc";中,並沒有通過new()來創建實例,是不是違反了上述原則?其實沒有。
5. 關於String str = "abc"的內部工作。Java內部將此語句轉化為以下幾個步驟:
(1)先定義一個名為str的對String類的對象引用變數:String str;
(2)在棧中查找有沒有存放值為"abc"的地址,如果沒有,則開辟一個存放字面值為"abc"的地址,接著創建一個新的String類的對象o,並將o的字元串值指向這個地址,而且在棧中這個地址旁邊記下這個引用的對象o。如果已經有了值為"abc"的地址,則查找對象o,並返回o的地址。
(3)將str指向對象o的地址。
值得注意的是,一般String類中字元串值都是直接存值的。但像String str = "abc";這種場合下,其字元串值卻是保存了一個指向存在棧中數據的引用!
為了更好地說明這個問題,我們可以通過以下的幾個代碼進行驗證。
String str1 = "abc";
String str2 = "abc";
System.out.println(str1==str2); //true
注意,我們這里並不用str1.equals(str2);的方式,因為這將比較兩個字元串的值是否相等。==號,根據JDK的說明,只有在兩個引用都指向了同一個對象時才返回真值。而我們在這里要看的是,str1與str2是否都指向了同一個對象。
結果說明,JVM創建了兩個引用str1和str2,但只創建了一個對象,而且兩個引用都指向了這個對象。
我們再來更進一步,將以上代碼改成:
String str1 = "abc";
String str2 = "abc";
str1 = "bcd";
System.out.println(str1 + "," + str2); //bcd, abc
System.out.println(str1==str2); //false
這就是說,賦值的變化導致了類對象引用的變化,str1指向了另外一個新對象!而str2仍舊指向原來的對象。上例中,當我們將str1的值改為"bcd"時,JVM發現在棧中沒有存放該值的地址,便開辟了這個地址,並創建了一個新的對象,其字元串的值指向這個地址。
事實上,String類被設計成為不可改變(final)的類。如果你要改變其值,可以,但JVM在運行時根據新值悄悄創建了一個新對象,然後將這個對象的地址返回給原來類的引用。這個創建過程雖說是完全自動進行的,但它畢竟佔用了更多的時間。在對時間要求比較敏感的環境中,會帶有一定的不良影響。
再修改原來代碼:
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並沒有創建新對象)。當str1改完其值後,再創建一個String的引用str4,並指向因str1修改值而創建的新的對象。可以發現,這回str4也沒有創建新的對象,從而再次實現棧中數據的共享。
我們再接著看以下的代碼。
String str1 = new String("abc");
String str2 = "abc";
System.out.println(str1==str2); //false
創建了兩個引用。創建了兩個對象。兩個引用分別指向不同的兩個對象。
String str1 = "abc";
String str2 = new String("abc");
System.out.println(str1==str2); //false
創建了兩個引用。創建了兩個對象。兩個引用分別指向不同的兩個對象。
以上兩段代碼說明,只要是用new()來新建對象的,都會在堆中創建,而且其字元串是單獨存值的,即使與棧中的數據相同,也不會與棧中的數據共享。
6. 數據類型包裝類的值不可修改。不僅僅是String類的值不可修改,所有的數據類型包裝類都不能更改其內部的值。
7. 結論與建議:
(1)我們在使用諸如String str = "abc";的格式定義類時,總是想當然地認為,我們創建了String類的對象str。擔心陷阱!對象可能並沒有被創建!唯一可以肯定的是,指向String類的引用被創建了。至於這個引用到底是否指向了一個新的對象,必須根據上下文來考慮,除非你通過new()方法來顯要地創建一個新的對象。因此,更為准確的說法是,我們創建了一個指向String類的對象的引用變數str,這個對象引用變數指向了某個值為"abc"的String類。清醒地認識到這一點對排除程序中難以發現的bug是很有幫助的。
(2)使用String str = "abc";的方式,可以在一定程度上提高程序的運行速度,因為JVM會自動根據棧中數據的實際情況來決定是否有必要創建新對象。而對於String str = new String("abc");的代碼,則一概在堆中創建新對象,而不管其字元串值是否相等,是否有必要創建新對象,從而加重了程序的負擔。
(3)當比較包裝類裡面的數值是否相等時,用equals()方法;當測試兩個包裝類的引用是否指向同一個對象時,用==。
(4)由於String類的final性質,當String變數需要經常變換其值時,應該考慮使用StringBuffer類,以提高程序效率。
❻ java中的,堆,棧,還有方法區都是用來放什麼的
棧里存放的是值類型(int、float等)的值和引用類型(String、你自己創建的類對象等)在堆中的地址;堆中存放引用類u型的值,如果堆中某個值的地址在棧中沒有被指向,他就會被GC回收。
方法區存儲所有的類和靜態變數。
❼ java,中的堆和棧
參考我給別人同樣問題的回答吧
http://..com/question/16857.html
❽ JAVA中堆棧是什麼
= = 樓上的,樓上問的是JAVA的堆棧啊...
JAVA有struct這種東西,這玩笑開大了吧...
別用題目的一個的關鍵詞,然後找一堆內容硬套上去好不好~~~
堆棧是什麼,樓上的都說了...
在JAVA上,如果是J2ME上的話,就是可用內存...
如手機,在手機上的RAM與ROM都算是內存,但在運行JAVA程序時,
程序能操作的內存只能是系統劃分的堆棧空間....
❾ 請簡單通俗易懂的解釋一下在Java中什麼叫堆 什麼叫棧 謝謝
堆:也叫動態內存,相當於一個內存池子,在java中創建對象的時候,就從堆裡面拿出一塊來存放對象;當GC(垃圾回收)回收對象的時候,又把對象佔用的內容還給堆。
舉個例子:堆就好比一個面團,類就好比一個饅頭印子,用印子從面團中取出一小塊面團,印成饅頭,這個饅頭就是這個饅頭印子類產生的對象了。當無限的創建饅頭的時候,這個面團總會被用光的,這個時候就不能在創建新的饅頭了。
所有GC就有存在的必要了,當對象不被持有的時候,GC就會把對象還給堆。也就是,當這個饅頭沒有被使用,這個饅頭就變成小面團,還給面團。
棧:也是一段內存,但是這段內存比較有特點,遵循一個先進後出的規則。
舉個例子:吃過罐裝的薯片吧,薯片一片一片的放到罐裡面去,想想,最先放進去的是不是放在罐的最底部。現在一片片把薯片取出來,是不是要從最頂部開始去,也就是最後放進去的,最先取出來。這個薯片放進去和取出來的這個過程,就是棧的工作原理啦(先進入的後出來,後進入的先出來)
在java中的棧:棧的原理明白了,其實只要是計算機只要是編程語言,什麼堆什麼棧都是一樣的,基本作用也一樣。java中可以認為,棧用來存放局部變數的。
public void fun(){
int i=0; //i 是一個局部變數,存放在棧裡面的
Object obj = new Objec(); //obj 是一個對象應用,同樣也是一個局部變數,存放在站裡面的,但是obj指向的對象,在存在堆中
}
❿ java的堆是什麼堆
JAVA虛擬機將運行時的數據分成了幾大塊,1、程序計數器,2、虛擬機棧,3、本地方法棧,4、方法區,5、堆,java堆一般就是指這個,這個堆裡面存儲的都是通過new關鍵字產生的對象