[英]How does the static keyword work in Java?
我從一開始就閱讀Java教程 ,並且對字段或變量上的static
關鍵字有疑問。 就像Java
在這里說的那樣:
Class Variables (Static Fields)
類變量是使用static修飾符聲明的任何字段; 這告訴編譯器,無論該類被實例化了多少次,該變量確實存在一個副本。 可以將定義特定類型自行車的齒輪數的字段標記為靜態,因為從概念上講,相同數量的齒輪將應用於所有情況。
這樣,我想如果您有一個對象(在本例中為Bicycle
類的一個實例),並且在其內部有一個字段為其static
,則與您是否喜歡bicycle1
或bicycle2
,該字段為靜態將具有相同的值。 我是錯了還是我很了解?
我的意思是,如果我有:
Bicycle bicycle1 = new Bicycle();
Bicycle bicycle2 = new Bicycle();
在“ Bicycle
”課程中,我有一個static
字段,例如:
class Bicycle{
static int gears;
//Methods to set and get gears
}
在bicycle1
我將齒輪的值設置為七個:
bicycle1.setGears(7);
那么如果我嘗試獲取bicycle2
的齒輪值,我應該獲得與我在bicycle1
設置的齒輪值相同的值,對嗎?
System.out.println(bicycle2.getGears()); //7
好吧,這就是我所懷疑的地方,因為正如Java
在上面引述中所說的那樣:
這告訴編譯器該變量存在一個副本
此副本存儲在哪里? 對象如何訪問該副本? 該副本何時創建?
此副本存儲在哪里?
副本(靜態變量)存儲在“永久生成”部分中,但是如果您使用Java8,則“永久生成”部分不再存在。 靜態變量和靜態方法是反射數據的一部分,它們是與類相關的數據,與實例無關。
對象如何訪問該副本?
您創建的類(對象)的每個實例都有對該類的引用。
該副本何時創建?
它是在加載類時在運行時創建的:這是在首次引用該類時由JVM的類加載器完成的。
靜態變量屬於該類,而不屬於該類的實例。 您的直覺是正確的-無論您創建多少對象,您只有一個副本。
您可以使用類的名稱訪問靜態變量,如以下示例所示:
class Static {
static int staticField;
}
public class UseStatic {
public static void main(String[] args) {
System.out.println(Static.staticField);
}
}
靜態字段對於創建某種類常量很有用。
最后,要輕松地初始化特定類的靜態字段,可以使用靜態初始化塊 。
資料來源 :Java大學課程, Java官方文檔
這樣,我想如果您有一個對象(在本例中為Bike類的實例),並且在其內部有一個字段為其靜態,則與您是否喜歡Bicycle1或Bicycle2無關,該字段為靜態將具有相同的值。 我是錯了還是我很了解?
首次使用Java實例化類時,JVM將創建兩件事情 :
一個實例。 將為您創建的每個實例在堆上分配一組非靜態字段。 這些實例字段與所有其他實例分開(並用於表示其對象的狀態)。
一個Class對象。 Java中的每個類都有一個,只有一個Class對象……無論創建了多少個實例。 例如,類String
的Class對象是Class<String>
(表示為String.class
的文字)。 您可以認為類的靜態字段屬於Class對象。 類對象的生命周期與類實例的生命周期無關。 只要JVM進程正在運行,類對象就存在(因此,它們的靜態字段也存在那么長時間)。
由於一個類只有一個Class對象,並且一個類的所有實例都共享同一個Class對象,所以所有存在的類實例都共享一個類的靜態字段。
通常,將static
關鍵字理解為“獨立於任何實例”是有用的:
Java中的靜態變量存儲在該類中,您無需創建它的實例即可訪問它們。
class Bicycle{
public static int gears = 7;
//Methods to set and get gears
}
您可以像這樣訪問靜態方法
Bicycle.gears;
因此,在Java上僅聲明了一個Bicycle類,當您實例化一個類時,它將創建一個聲明了所有靜態屬性的Bicycle實例。
此副本存儲在哪里?
靜態變量存儲在某些靜態存儲中(我相信在permgen中),您不必理會它。
該副本何時創建?
它們是在首次訪問類(由類加載器加載)時創建的,並且從不刪除(除非卸載了類)
對象如何訪問該副本?
實例引用了其類,而類則尊重其所有變量。 具體如何實現C結構在內存中的具體放置方式。
由於靜態變量是綁定到類而不是實例的,因此您甚至不需要實例化類來訪問它們。 MyClass.myStaticVar
可以。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.