簡體   English   中英

static關鍵字在Java中如何工作?

[英]How does the static keyword work in Java?

我從一開始就閱讀Java教程 ,並且對字段或變量上的static關鍵字有疑問。 就像Java 在這里說的那樣:

Class Variables (Static Fields)類變量是使用static修飾符聲明的任何字段; 這告訴編譯器,無論該類被實例化了多少次,該變量確實存在一個副本。 可以將定義特定類型自行車的齒輪數的字段標記為靜態,因為從概念上講,相同數量的齒輪將應用於所有情況。

這樣,我想如果您有一個對象(在本例中為Bicycle類的一個實例),並且在其內部有一個字段為其static ,則與您是否喜歡bicycle1bicycle2 ,該字段為靜態將具有相同的值。 我是錯了還是我很了解?

我的意思是,如果我有:

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關鍵字理解為“獨立於任何實例”是有用的:

  • 靜態字段屬於Class對象,而不屬於任何實例
  • 靜態方法是通過Class對象調用的,無法直接訪問任何實例
  • 靜態成員類實例不依賴於任何其他實例

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM