目錄
Java變量在內存中的存儲
以下探究成員變量和局部變量在內存中的存儲情況。
package com.my.pac04;
/**
* @author Summerday
* @date 2019/12/1 13:05
*/
public class ValStoreTest {
public static void main(String[] args) {
//分別創建兩個Value類的實例,val0和val1
Value val0 = new Value();
Value val1 = new Value();
//修改val0的num值
val0.num = 5;
System.out.println("val0's num = " + val0.num);//val0'num =5
System.out.println("val1's num = " + val1.num);//val0'num =0
//直接使用類調用類變量
Value.staticNum = 10;
//使用實例對象調用類成員變量,不建議使用
//val0.staticNum = 10;
System.out.println("val0's staticNum =" + val0.staticNum);//10
System.out.println("val1's staticNum =" + val1.staticNum);//10
}
}
class Value {
public int num;//實例變量
public static int staticNum;//類變量
}
成員變量
上面提到成員變量分為實例變量和類變量。這兩者在內存中的存儲形式又是如何呢?
class Value {
public int num;//實例變量
public static int staticNum;//類變量
}
實例變量
Value val0 = new Value();
Value val1 = new Value();
//修改val0的num值
val0.num = 5;
System.out.println("val0's num = " + val0.num);//val0'num =5
System.out.println("val1's num = " + val1.num);//val0'num =0
- 在堆區開辟內存,存放實例變量,並默認初始化。
- 在棧區聲明引用變量val0和val1,讓他們分別存儲兩個堆區對象的地址,意思是讓引用變量指向實際對象。
- 兩個對象分別獨立,互不影響。
類變量
//直接使用類調用類變量
Value.staticNum = 10;
//使用實例對象調用類成員變量,不建議使用
//val0.staticNum = 10;
System.out.println("val0's staticNum =" + val0.staticNum);//10
System.out.println("val1's staticNum =" + val1.staticNum);//10
- 在方法區(不是棧區)存儲static修飾的變量,即staticNum。
- 兩個引用變量val0和val1還是在棧區存儲,且他們指向方法區的同一塊內存區域。
- 在同一個類中,實例對象共享類變量。意思是,如果Java程序運行在不同JVM進程中,就不會共享數據。如下:
package com.my.pac04;
/* ClassVal.java */
public class ClassVal {
public static int value = 6;
}
package com.my.pac04;
/* ClassValTest01.java */
public class ClassValTest01 {
public static void main(String[] args) {
ClassVal val01 = new ClassVal();
val01.value = 10;//修改static修飾的值為10
System.out.println(val01.value);
}
}
package com.my.pac04;
/* ClassValTest02.java*/
public class ClassValTest02 {
public static void main(String[] args) {
ClassVal val02 = new ClassVal();
System.out.println(val02.value);//不是10,而是6
}
}
關於JVM及類加載的機制,在之后的學習之中將會繼續深入,在這里就不發表自己的膚淺之談了,之后會進行補充哈。
局部變量
- 定義局部變量時,只有對他進行初始化賦值之后,才會獲得系統給予的內存。
- 局部變量不屬於類或實例,總是保存在棧內存中,所以隨方法或代碼塊結束而結束,后進先出。
- 基本數據類型存放具體數值,引用類型存放實際引用對象的地址值。
注意:雖然大部分時間,可以之間用成員變量來代替局部變量解決問題,但是這種做法,有幾個缺點:
- 增大變量的生存時間,增加內存開銷。
- 擴大變量的作用域,不利於提高程序的內聚性。
局部變量的作用范圍越小,它在內存中停留的時間就越短,程序性能就會越好。
總結
- 假如定義的變量用於描述某個類或對象的固有信息,請用成員變量。
- 假如定義的變量用於保存類或實例運行的狀態信息,請用成員變量。
- 假如定義的變量用於保存共享在多個方法間的消息,請用成員變量。