對象在內存中的具體存儲方式到底是什麼樣子的呢?這就要提出“對象引用”這個概念
public class Test
{
public static void main(String[] args)
{
Human aPerson = new Human(160);
}
}
class Human
{
/**
* constructor
*/
public Human(int h)
{
this.height = h;
}
/**
* accessor
*/
public int getHeight()
{
return this.height;
}
/**
* mutator
*/
public void growHeight(int h)
{
this.height = this.height + h;
}
private int height;
}
一般創建類的對象的時候直接使用new給類開闢空間。
Human aPerson = new Human(160);
這個語句的具體操作是什麼呢? ^_^
1. 首先看等號的右側,new是在內存中爲對象開闢空間,具體來說,new是在內存的堆(heap)上爲對象開闢空間。這一空間中,保存有對象的數據和方法。
2. 等號左側,aPerson指代一個human對象,這個被稱爲對象引用。實際上,aPerson並不是對象本身,而是類似於指向對象的指針。aPerson存在於內存的棧(Stack)中。
3. 當我們用等號賦值時,是將對象在內存中的地址賦給對象引用aPerson。
Java在編譯運行時所說的內存指的是JVM(Java Virtual Machine)虛擬出來的Java線程內存空間。
每當線程調用一個Java方法時,JVM就會在該線程對應的棧中壓入一個幀。Java棧和幀在內存中也不必是連續的,棧是以幀爲單位保存當前線程的運行狀態。
<1> 棧的讀取速度比堆快,但棧上存儲的數據受到有效範圍的控制,C語言中一次函數調用結束,棧最底部的棧幀消除,裏面存儲的參量和變量自動消失。Java中棧也是這樣。Java中所有的普通對象都存儲在堆上,也就是說new的時候是在堆上面開闢一個類的對象的空間。
human h1 = new human(121);
human h2 = h1;
當你執行這個操作的時候內存中一共只有一個對象,兩個指針都指向這個對象。使用h2對對象進行操作的時候h1這邊也會看到。
<2> 基本類型的對象呢?比如說int,double,都保存在棧上。基本類型是不需要new的,聲明的時候直接 int(double) var1;一旦聲明,將直接在棧上直接存儲基本類型的數據。所以基本類型的變量名也不叫作引用。
講了很基礎的對象和引用後,有一個問題Java中參數傳遞是值傳遞呢還是引用傳遞?
我的理解是: Java的參數傳遞爲值傳遞。也就是說,當我們傳遞一個參數時,方法將獲得該參數的一個拷貝。
Java中參數的傳遞應該就是兩種情況:基本類型的參數和引用類型的參數。
1> 基本類型的值傳遞是說變量本身被複制並傳遞給Java方法,Java方法對該副本的修改不會影響原來的變量。
2> 引用的值傳遞指的是對象的地址被傳過去,Java方法中的行參會指向堆裏面的對象,在Java方法中對對象的修改是影響到原對象的。