Java的堆是一個運行時資料區,類別的(物件從中分配空間。這些物件透過new、newarray、anewarray和multianewarray等指令建立,它們不需要程式碼來明確的釋放。堆是由垃圾回收來負責的,堆的優勢是可以動態地分配記憶體大小,生存期也不必事先告訴編譯器,因為它是在運行時動態分配記憶體的,Java的垃圾收集器會自動收走這些不再使用的資料。但缺點是,存在堆疊中的資料大小與存活期必須是確定的,缺乏彈性。物件句柄。 ;首先它會在棧中創建一個變數為a的引用,然後查找棧中是否有3這個值,如果沒找到,就將3存放進來,然後將a指向3。完b的引用變數後,因為在堆疊中已經有3這個值,便將b直接指向3。令a=4;那麼編譯器會重新搜尋堆疊中是否有4值,如果沒有,則將4存放進來,並令a指向4;如果已經有了,則直接將a指向這個位址。改變不會影響到b的值。影響到b, 它是由編譯器完成的,它有利於節省空間。的包裝類別資料。會建立一個新的物件。進棧,並令str指向”abc”,如果已經有”abc” 則直接令str指向“abc”。當一個包裝類別的引用是否指向同一個物件時,用==,下面用例子說明上面的理論。
int a = 3; int b = 3;
String str = new String("abc"); String str = "abc";
用new的方式是產生不同的物件。每一次生成一個。
因此用第一種方式創建多個”abc”字符串,在內存中其實只存在一個對象而已. 這種寫法有利與節省內存空間. 同時它可以在一定程度上提高程序的運行速度,因為JVM會自動根據堆疊中資料的實際情況來決定是否有必要建立新物件。而對於String str = new String("abc");的程式碼,則一概在堆中建立新對象,而不管其字串值是否相等,是否有必要建立新對象,從而加重了程式的負擔。
另一方面, 要注意: 我們在使用諸如String str = "abc";的格式定義類別時,總是想當然地認為,創建了String類別的物件str。擔心陷阱!物件可能並沒有被創建!而可能只是指向一個先前已經建立的 物件。只有透過new()方法才能保證每次都建立一個新的物件。
由於String類別的immutable性質,當String變數需要經常變換其值時,應該考慮使用StringBuffer類,以提高程式效率。 Java的堆是一個運行時資料區,類別的(物件從中分配空間。這些物件透過new、newarray、anewarray和multianewarray等指令建立,它們不需要程式碼來明確的釋放。堆是由垃圾回收來負責的,堆的優勢是可以動態地分配內存大小,生存期也不必事先告訴編譯器,因為它是在運行時動態分配內存的,Java的垃圾收集器會自動收走這些不再使用的數據。缺點是,由於要在運行時動態分配內存,訪問速度較慢。資料類型;
2、 java中雖然沒有說明程式在運作的時候,記憶體是如何分配的,不過通常java開發人員或學習者,會將記憶體分為三個區域:堆疊空間、堆空間、方法區;
堆區:
a.儲存的全部是對象,每個對像都包含一個與之對應的class的資訊。 )
b.jvm只有一个堆区被所有线程共享,堆中不存放基本类型和对象引用,只存放对象本身
栈区:
a.每个线程包含一个栈区,栈中只保存基础数据类型的对象和自定义对象的引用(不是对象),对象都存放在堆区中
b.每个栈中的数据(原始类型和对象引用)都是私有的,其他栈不能访问。
c.栈分为3个部分:基本类型变量区、执行环境上下文、操作指令区(存放操作指令)。
方法区:
a.又叫静态区,跟堆一样,被所有的线程共享。方法区包含所有的class和static变量。
b.方法区中包含的都是在整个程序中永远唯一的元素,如class,static变量。字符串常量在方法区分配 ,数组既在栈空间分配数组名称, 又在堆空间分配数组实际的大小。
上面明白之后,接下来我们来分析 String str=new String("abc");
String str 是定义了一个String类型的变量,此时只定义了而没有创建对象,而new Sring(“abc”)到底做了什么?我们可以查看String的源码,发现如下:
public final class String
implements java.io.Serializable, Comparable
{
/** The value is used for character storage. */
private final char value[];
……
发现她有一个Value的属性,类型是char[],而此数组又做了什么事情?如果读源码会发现他保存了String对象的值,此时也说明String就是char[]来组织的。
当执行String a="abc";时,JAVA虚拟机会在栈中创建三个char型的值'a'、'b'和'c',然后在堆中创建一个String对象,它的值(value)是刚才在栈中创建的三个char型值组成的数组{'a','b','c'}对象,而这个新创建的String对象会被添加到字符串池中。
此时就存在了两个对象:一个在堆中;一个在字符串池中。
/**************************************************************************************************************************/
String str1 = "abc"; String str2 = new String("abc");
以上是Java中基本型別與封裝型別資料與堆疊、堆疊的關係總結的詳細內容。更多資訊請關注PHP中文網其他相關文章!