2015-01-07 64 views
4

最近,我正在經歷a page on javarevisited,發現它要求讀者確定什麼將是它輸出的代碼塊...如何從空引用中訪問靜態變量?

雖然我得到的輸出我不滿意的結果(這外面傳來TO BE「Hello」),因爲我不知道如何從空引用訪問靜態成員。背景中發生了什麼?

public class StaticDEMO { 

    private static String GREET = "Hello"; 

    public static void main(String[] args) { 
     StaticDEMO demo = null; 
     System.out.println(demo.GREET); 
     // TODO code application logic here 
    } 
} 
+0

因爲它實際上沒有使用參考。 – immibis

+1

'StaticDEMO演示;'編譯器知道'demo'是一個類的引用,它可能是null,但是它的類型是'StaticDEMO',它是你的類..這不是一個對象... ..因爲靜態字段是在編譯時確定,這是可以的。 –

回答

12

這是有效的,因爲JVM知道您正試圖訪問特定類上的靜態成員。因爲您必須將demo聲明爲特定類別(在本例中爲StaticDEMO),因此它知道使用它來查找GREET

要清楚,你不會經常遇到這種情況(實際上我不得不輸入這個代碼來驗證它,我不能說我見過這個)。主要的是,總是通過它們的類來引用靜態字段,而不是對象實例(可能爲空,正如我們所看到的!),這是一個很好的做法。

含義,更喜歡這個:

System.out.println(StaticDEMO.GREET); 

編輯

我發現在Java Specification這個參考:第15章,第11節:現場訪問表達式。

例15.11.1-2。接收器變量是無關緊要對於靜態字段訪問

下面的程序說明了一個空引用可用於訪問類(靜態)變量,而不會引起一個異常

[例如這裏未示出爲了簡潔]

+1

但是看着這段代碼,很可能它會在運行時拋出NULLPOINTEREXCEPTION或NULLREFERENCEEXCEPTION .. 我的查詢是如何工作的???我們已經被教導過,靜態成員是類成員,只能通過類的名字訪問。那麼,在這種情況下,如何從一個空引用變量訪問一個靜態成員? :/ –

+3

因爲它根本不使用參考,只是參考的類型。即使在使用對象而不是類引用靜態字段時,JVM也知道對象的類型(CLASS)並將其用於封面下。該規範明確稱這是合法的(Sec 15.11.1)。 – Todd

4

在Java中被靜態裝飾的任何方法意味着該方法是一個類級別的記憶。這意味着,你不需要一個對象來指定靜態成員。靜態方法/變量由類本身維護,而不是由類的任何實例維護。在你的例子中,編譯器已經知道該成員是靜態成員,並且不需要任何實例來訪問該靜態方法。

+0

我完全同意你@Yadu,我知道靜態方法/變量由類本身維護,而不是由類的任何實例,但我的問題是如何從空引用訪問它? –

+0

由於JVm知道您嘗試訪問的方法是靜態方法,因此它將忽略該實例。因爲,即使您嘗試使用該類的不同實例訪問靜態方法,也會返回相同的方法/相同的結果。 –

2

靜態成員與類存儲在一起,而不是與它的任何特定實例一起存儲。所以,實例是否爲null並不重要 - 類的成員仍然可以訪問。

0

JVM只是簡單地忽略null,因爲GREET是一個類字段而demo是無關的引用Class字段。

Static方法不需要對象引用來調用它,所以你可以調用它,即使引用該對象是null

+1

很好地解釋了:) –

+0

你是否嘗試運行你認爲java將原始代碼作爲代碼的代碼? – Cthulhu