[英]Accessing a static variable via an object reference in Java
為什么我們可以通過 Java 中的對象引用訪問靜態變量,如下面的代碼?
public class Static {
private static String x = "Static variable";
public String getX() {
return this.x; // Case #1
}
public static void main(String[] args) {
Static member = new Static();
System.out.println(member.x); // Case #2
}
}
一般來說,公共變量可以被所有人訪問,而私有變量只能從類的當前實例內部訪問。 在您的示例中,您可以從main
方法訪問x
變量,因為該方法位於 Static 類中。
如果您想知道為什么允許您從靜態類的另一個實例而不是您當前所在的實例訪問它(通常不允許私有變量),這僅僅是因為靜態變量不存在於每個實例的基礎上,但在每個類的基礎上。 這意味着可以從A 的所有實例訪問A的相同靜態變量。
如果不是這種情況,則根本沒有人能夠訪問私有靜態變量,因為它不屬於一個實例,而是屬於所有實例。
允許的原因是 JLS 說它是。 允許這樣做的特定部分是JLS 6.5.6.2 (對於member.x
情況)和JLS 15.11.1 (在這兩種情況下)。 后者說:
如果字段是靜態的:
如果該字段是非空的 final 字段,則結果是作為 Primary 表達式類型的類或接口中指定的類變量的值。
如果該字段不是 final,或者是一個空白 final 並且字段訪問發生在類變量初始化器(第 8.3.2 節)或靜態初始化器(第 8.7 節)中,則結果是一個變量,即指定的類變量作為 Primary 表達式類型的類。
為什么 JLS 允許這些?
坦白說,我不知道。 我想不出有什么好的理由允許他們。
無論哪種方式,使用引用或this
來訪問靜態變量都是一個壞主意,因為大多數程序員可能會誤以為您正在使用實例字段。 這是不使用 Java 的這個特性的一個強有力的理由。
在第一種和第二種情況下,您應該將變量引用為x
或Static.x
而不是member.x
。 (我更喜歡Static.x
。)
以這種方式引用靜態變量不是最佳做法。
但是你的問題是為什么允許? 我猜答案是開發人員可以將實例成員(字段或變量)更改為靜態成員,而無需更改對該成員的所有引用。
在多開發人員環境中尤其如此。 否則,您的代碼可能無法編譯,因為您的合作伙伴將某些實例變量更改為靜態變量。
靜態變量也稱為類變量,因為它們可用於該類的每個對象。
由於成員是靜態類的對象,因此您可以通過成員對象訪問靜態類的所有靜態變量以及非靜態變量。
非靜態成員是實例成員。 靜態成員(類寬)無法訪問實例成員,因為無法確定哪個實例擁有任何特定的非靜態成員。
實例對象總是可以引用靜態成員,因為它屬於全局(共享)到其實例的類。
這在邏輯上是有道理的,盡管這不是有趣的做法。 靜態變量通常用於在實例化期間強制執行變量的單一聲明。 對象是具有其他名稱的類的新副本。 即使對象是類的新副本,它仍然具有(未實例化的)類(第一個不可見實例)的特征。 因此,新對象也具有指向原始副本的靜態成員。 需要注意的是:StackOverflow 的新實例也是 StackOverflow。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.