2012-07-25 41 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 

这样你就可以在同一类的相同的静态字段中看到两个不同的值,通过使用不同的类加载器。

但是这是一个很奇怪的情况...