2014-07-24 80 views
-1

在下面的例子中,是分配給j的內存嗎?如果是這樣,假設j永遠不會被初始化,那麼j的地址是否可以在整個程序中改變?Java中內存中未初始化的靜態變量

public class c{ 
    private static String j; 
    public c(){} 
    .... 
} 
+0

Java沒有「地址」的概念。 – immibis

+0

你是否有機會談論引用id?-1。 –

+0

我不明白你在問什麼......你可以讓它更清楚一點嗎? –

回答

-1

Java不是ç ...每塊數據(甚至靜態變量)被隱式初始化(​​經常null或0),編譯器將不接受uninitiliazed局部變量。發現this explanation

+1

方法中的局部變量也是這樣嗎? – JonK

+0

是的,AFAIK,局部變量也被隱式地初始化.... –

+5

我很肯定他們不會 – JonK

1

首先,它是Java。所以沒有談到地址訪問和地址改變。

編譯器代表用戶完成所有這些工作,以實現程序的優化和高效性。

接下來,由於變量j已聲明爲靜態,所以不能決定地址,但即使在塊結束後,它的值也將永久存在,除非已更改。 (這意味着即使訪問塊並聲明它改變,它也不會丟失值。)

它只會在程序終止後失去它的值!

1

在下面的例子中是分配給j的內存嗎?

內存由JVM分配給包含j靜態變量的幀。並且它默認初始化爲null。但是,null不引用任何堆節點。

如果是這樣,假設j永遠不會被初始化,那麼整個程序中j的地址是否會改變?

沒有指定,但基於我對JVM如何實現的理解,是的,j的地址可能會改變。

但是,除非程序試圖從本機代碼(或等效代碼)訪問j,否則它不會知道該地址或可能對其進行的更改。

+0

框架,如在方法調用堆棧或其他地方? –

+0

不是堆棧幀/本地幀。與班級相關的框架。 (實際上,JVM規範並沒有提到靜態變量是如何/在哪裏表示的,它只是說使用getStatic/putStatic字節碼來訪問/設置它們...... –

+0

當靜態變量(一個對象)未被明確初始化時,(默認爲空),它是否需要任何內存? –

2

JVM將延遲加載一個類。在首次引用該類時,該類將被分配,並且會爲所有靜態字段佈置「是」內存。在這種情況下,j將保持'空'。類和它的字段將被分配的地方將取決於JVM,並且最具體的是被選中的垃圾收集器。

Java語言不像其他語言(如C)那樣直接訪問底層內存地址。是的,如果垃圾收集器決定重新定位類,則底層內存地址可能會更改爲/ when /;有些地方選區不會重新安置班級,舊班級甚至無法收回班級。需要注意的是,GC的任何移動對Java程序都是不可見的。也就是說,只要您避免使用sun.misc.Unsafe,sun.misc.Unsafe就是Java 5中添加的JVM的後門。

有關Unsafe的更多詳細信息,此blog有一個很好的概述。

+0

只是我的2美分,因爲j是一個字符串,它是一個不可變的對象,每當j的值改變時jvm會創建一個新的對象,所以j的引用也會改變 – holap

+0

@holap - 兩個不同的東西,存儲「j」指向一個對象的指針,並且對象的存儲精靈(如果有的話)。由於對象是不可變的,所以必須創建一個新的對象,但是指針本身只能將其值更改爲指向新對象,而不是其存儲位置。改變指針本身的存儲位置往往只是爲了方便JVM及其內存管理器而發生。 –

0

你可以說它會指向null參考。Java中的內存使用動態內存運算符(即new運算符)分配(像String這樣的某些類具有可使用=運算符初始化的特殊權限)。