2017-08-08 289 views
-2

我需要一些幫助來澄清靜態變量和非靜態變量。我的理解是,靜態變量在類的所有實例中具有相同的值。但是,假設我在同一個類中混合使用了靜態變量和非靜態變量。當我引用一個靜態變量時,無論使用哪個實例,我都會得到相同的值?然而,當我引用一個非靜態變量時,我將獲得與該特定類相關的值?這似乎是一個記憶管理的噩夢。這真的是如何工作,以及如何處理靜態內存?是在每個實例中創建的變量的多個副本,然後以某種方式同步或作爲每個實例中創建的地址的引用?在同一個類中使用混合靜態變量和非靜態變量是否有任何缺陷? TIA。同一類中的Java靜態變量和非靜態變量

+1

'當我引用靜態變量,不管哪一個實例used' - >你不需要(並且不應該)使用實例來獲取靜態變量的值。例如,您應該使用以下語法獲得它的值:'YourClass.YOUR_STATIC_FINAL_VARIABLE'。正如你所看到的,不需要'new YourClass()。something'。 –

+0

謝謝,但答覆不是我正在做的。我使用'myclass1 = new MyClass(); myclass2 = new MyClass();'。然後,我將靜態變量引用爲'myclass1.something'或'myclass2.something',並期望它們具有相同的值。同時,'myclass1.somethingelse'和'myclass2.somethingelse'會有不同的值。這正是我想要驗證的,並知道是否有任何缺陷。 –

回答

4

你在斷言中是正確的......排序。由於您不需要類實例來引用一個實例,所以靜態實際上並不真正共享該類的實例。

public class Foo { 
    public static String MYSTRING = "test"; 
} 

可以不富

的實例
String localString = Foo.MYSTRING; 

我真的不會擔心太多關於JVM如何選擇存儲爲靜態變量的內存引用來訪問,這是一個實現細節被委派給JVM設計者。

有一個定義靜態和非靜態(實例)變量的類沒有任何缺陷,它始終在發生,並且非常自然......只要您瞭解靜態如何工作,看來你是這樣做的。

+0

謝謝。我認爲是這樣,但只是需要溫暖和模糊。 –

2

OCA Java SE 7 Programmer I Certification Guide: Prepare for the 1ZO-803 exam摘自:

靜態變量

靜態變量屬於一類。它們對於一個類的所有實例都是通用的,並且對任何一個類的實例都不是唯一的。靜態屬性獨立於類的任何實例存在,並且即使沒有創建類的實例也可以訪問。您可以將靜態變量與共享變量進行比較。靜態變量由類的所有對象共享。

靜態方法

靜態方法不與對象相關聯,並且不能使用任何一個類的實例變量。您可以定義靜態方法來訪問或操控靜態變量

您也可以使用靜態方法來定義的實用方法,這些方法通常操縱方法的參數來計算並返回一個適當的值

在非私人靜態變量和方法由派生類繼承。靜態成員不參與運行時多態性。您無法重寫派生類中的靜態成員,但可以重新定義它們。如果您不知道繼承和派生類,那麼對靜態方法及其行爲的任何討論都會非常混亂。

0

Static變量在整個程序中都是相同的,因爲它們沒有實例化。這確實是具有靜態變量的全部要點。它們不是「某種程度上相同的值」,它們是相同的值,因爲它們從來沒有實例化過,並且在運行時只有一個來自同一類的同名靜態變量。

0

我不知道「記憶邏輯」的背後,但我已經創建了一個例子

public class TestClass { 

private static int a = 1; 
private int b = 1; 

public static void main(String[] args) { 
    TestClass firstInstance = new TestClass(); 
    TestClass secondInstance = new TestClass(); 

    // 'a' shouldn't be accessed like firstInstance.a, use TestClass.a instead(!) 
    System.out.println("firstInstance a: "+firstInstance.a+" b: "+firstInstance.b); // firstInstance a: 1 b: 1 
    System.out.println("secondInstance a: "+secondInstance.a+" b: "+secondInstance.b);// secondInstance a: 1 b: 1 

    firstInstance.a = 2; 
    firstInstance.b = 2; 

    System.out.println("firstInstance a: "+firstInstance.a+" b: "+firstInstance.b); //firstInstance a: 2 b: 2 
    System.out.println("secondInstance a: "+secondInstance.a+" b: "+secondInstance.b);//secondInstance a: 2 b: 1 
    //a is now 2 also for 'secondInstance' because it's static, secondInstance.b didn't change because b exists specifically for each instance 

    /* 
    * You can access 'a' even when no instance of TestClass exists 
    * think about a simple Dog class where the amount of legs is 4 for every dog, so you can make it static, 
    * but not every Dog has the same name, so it wouldn't be clever to make the name static 
    */ 
} 
}