Aaron
Aaron

Reputation: 11673

How is the value of a static / class variable passed around?

A static / class variable is defined in a type / class and is said to associate with the type / class that it is defined in and is independent of an instances of the type / class. There is exactly one static / class variable in the type / class and is best used for constant like properties, whose value would be common amongst any instances of the class. The state of a static / class variable is always exists in the class and therefore there is only one variable at any moment in the class and the keyword static is used to define this nature of the variable. The static / class variable in best practice is to be initialized once and this is ensured using the keyword final. A final static variable is to be initialized with an immutable collection as in a new String() or new Integer();

Now my question is how is the value from the static variable used? And what is the use of this variable called? E.g does it copy it's value from the class that it is contained in or is it an explicit reference to the variable in the class?

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.

    }
}

Upvotes: 3

Views: 138

Answers (4)

Pablo Grisafi
Pablo Grisafi

Reputation: 5047

As @Francisco Spaeth has pointed, the JLS is clear: there is only one static value shared between the instances.
But a class can be loaded in the same program with different classLoaders, and that means it may have a different static value for each classLoader. As an example:

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));

    }

}

If you run this code you will be something like

193798032450350
193798062432257

so you can see two different values in the same static field of the same class, by using different classloaders.

But that is a very strange case...

Upvotes: 0

corsiKa
corsiKa

Reputation: 82579

There is space specifically allocated for the storage of static variables. This is specified in the JLS, 8.3.1.1, which states

If a field is declared static, there exists exactly one incarnation of the field, no matter how many instances (possibly zero) of the class may eventually be created. A static field, sometimes called a class variable, is incarnated when the class is initialized.

It's worth noting that these variables aren't open for garbage collected until the class is unloaded (which doesn't usually happen often), which is a potential for unintended memory references being held.

Accessing static members could possibly be referred to as 'static access' (I've heard it used before) but generally it doesn't have its own term.

Upvotes: 5

Francisco Spaeth
Francisco Spaeth

Reputation: 23903

It is simply a reference.

In this case, as commonValue is defined as final and String is immutable, you cannot see it. But suppose the following code:

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);
    }

}

Upvotes: 1

LastStar007
LastStar007

Reputation: 765

Static variables associate with the class itself, not among instances of the class. Anything marked with the static keyword is initialized when the class is loaded at run-time. This is why you can call them with the class name and why you can use them without creating an object.

The JLS specifies that using a static variable is called: using a static variable. Just kidding.

Upvotes: 1

Related Questions