2012-07-25 57 views
3

靜態/類變量在類型/類中定義,並且被稱爲與它所定義的類型/類關聯,並且與類型/類的實例無關。在類型/類中只有一個靜態/類變量,最適合用於常量類屬性,其值在類的任何實例中都是常見的。靜態/類變量的狀態總是存在於類中,因此在類中的任何時刻只有一個變量,而關鍵字static用於定義變量的這種性質。最佳實踐中的靜態/類變量將被初始化一次,並使用關鍵字final來確保。一個最終的靜態變量將被初始化爲一個新的String()或new Integer();靜態/類變量的值是如何傳遞的?

現在我的問題是如何使用靜態變量的值? 這個變量的用途是什麼?例如,它是從它所包含的類複製它的值,還是它是對類中變量的明確引用?

e.g

class GenericType { 
    private final static String commonValue = new String("foobar"); 
} 
class AnotherGenericType { 
    public static void main(String[] args) { 
     System.out.println(GenericType.commonValue); //Displays foobar in the console. 

    } 
} 

回答

5

有專門分配給static變量的存儲空間。這在JLS, 8.3.1.1規定,如果某個字段聲明爲static其中規定

,存在只有一個化身領域的 ,不管有多少個實例(可能爲零)的 類的可能最終被創建。一個靜態字段,有時稱爲 類變量,在類初始化時體現出來。

值得注意的是,在類被卸載之前(這通常不會經常發生),這些變量不會打開以進行垃圾收集,這可能導致意外的內存引用被保留。

訪問靜態成員可能被稱爲「靜態訪問」(我聽說之前使用),但通常它沒有自己的任期。

1

靜態變量關聯與類本身,而不是該類的實例之一。在運行時加載類時,會初始化任何標有static關鍵字的內容。這就是爲什麼你可以用類名來調用它們,爲什麼你可以在不創建對象的情況下使用它們。

的JLS指定使用靜態變量稱爲:using a static variable。開玩笑。

1

這只是一個參考。

在這種情況下,由於commonValue定義爲finalString是不可變的,所以您看不到它。但是,假設下面的代碼:

public class GenericType { 
    public static Collection myCollection = new ArrayList(); 
} 

public class Test { 

    public static void main(String[] args) { 
     // you are accessing the public static field 
     GenericType.myCollection.add("first item"); 
     System.out.println(GenericType.myCollection); 

     // now c holds a reference for the collection that is referred by myCollection field 
     Collection c = GenericType.myCollection; 
     GenericType.myCollection.add("second item"); 
     GenericType.myCollection = new ArrayList(); 

     // printing the object referred by c (the old reference hold by myCollection field) 
     System.out.println(c); 

     // and here the current reference of myCollection field 
     System.out.println(GenericType.myCollection); 
    } 

} 
+1

假設下面的代碼是什麼? – LastStar007 2012-07-25 18:25:38

0

作爲@Francisco斯佩思所指出,該JLS是明確的:只有一個實例之間共享的靜態值。
但是一個類可以用不同的類加載器加載到同一個程序中,這意味着它可能對每個類加載器都有不同的靜態值。 作爲一個例子:

package classloaders; 

import java.lang.reflect.Field; 
import java.net.URL; 
import java.net.URLClassLoader; 

class SampleClass{ 
    static public final long loadTime = System.nanoTime(); 
} 

public class Main { 

    public static void main(String[] args) throws Exception { 

     URL url = new URL("file:///C:/workspaces/personal/JavaTest/bin/"); 
     ClassLoader cl1 = new URLClassLoader(new URL[]{url}, null); 
     ClassLoader cl2 = new URLClassLoader(new URL[]{url}, null); 

     Class<SampleClass> sampleClass = (Class<SampleClass>) cl1.loadClass("classloaders.SampleClass"); 
     Field field1 = sampleClass.getField("loadTime"); 
     field1.setAccessible(true); 
     System.out.println(field1.get(null)); 

     Class<SampleClass> sampleClass2 = (Class<SampleClass>) cl2.loadClass("classloaders.SampleClass"); 
     Field field2 = sampleClass2.getField("loadTime"); 
     field2.setAccessible(true); 
     System.out.println(field2.get(null)); 

    } 

} 

如果你運行這段代碼,你會像

193798032450350 
193798062432257 

這樣你就可以在同一類的相同的靜態字段中看到兩個不同的值,通過使用不同的類加載器。

但是這是一個很奇怪的情況...