Java for Beginners: Static Variables -- What Are They?

What are static variable in Java, and what are they for? A static variable is one that's associated with a class, not objects of that class.

Let's take a look at an example. To keep things as simple as possible, we'll use a public static variable. If you haven't come across public yet, don't worry about it! In these particular examples, actually it makes no difference.

Let's say you define a class like the following, with just one public static variable.

Stuff.java:

public class Stuff {
    public static String name = "I'm a static variable";
}




We've declared a class called 'Stuff' and given it one public static variable of type String. We've initialised the variable to the String value "I'm a static variable".

Now we can use this class in our main program like this:

Application.java:

public class Application {
    
    public static void main(String[] args) {
        System.out.println(Stuff.name);
    }

}





I'm a static variable







The point of the Application class here is just to give us somewhere to put a main method, which is the program entry (starting) point.

You can see that we can happily access the 'name' instance variable in the Stuff class without actually creating an object of type Stuff. We can just use the Stuff class directly. That's because the variable is static, and hence belongs to the class, not any particular object of that class.

The fact that we declared it public allows us to access it from other classes (Application in this case). Although actually in this example the public keyword is superfluous as it happens, due to us not having mentioned any package names.

Using the Static Keyword to Create Constants



One common use of static is to create a constant value that's attached to a class. The only change we need to make to the above example is to add the keyword final in there, to make 'name' a constant (in other words, to prevent it ever being changed).

We should also make 'name' uppercase by convention, to indicate that it's a constant. This isn't strictly necessary; it's literally just a convention.


public class Stuff {
    public final static String NAME = "I'm a static variable";
}





public class Application {
    
    public static void main(String[] args) {
        System.out.println(Stuff.NAME);
    }

}




I'm a static variable




Using Static Variable to Count Objects



Another classic use of static is to keep count of how many objects are created from a given class.

First, let's take a quick refresher on constructors.

A Quick Refresher On Constructors



We'll change the 'Stuff' class so that it has a constructor that accepts no parameters. A constructor is just a special method that's run whenever an object is created. The constructor has the same name as the class and no return type, not even void. You should declare it public so that it can always be invoked from outside the class itself (otherwise you won't be able to create objects from the class, at least not outside the package).


public class Stuff {
    public Stuff() {
        System.out.println("Stuff object constructed!");
    }
}





You can see that I've also added a println statement so that we can see when the constructor runs.

Now we'll modify the 'main' method so that it creates three objects of type 'Stuff'.


public class Application {
    
    public static void main(String[] args) {
        Stuff stuff1 = new Stuff();
        Stuff stuff2 = new Stuff();
        Stuff stuff3 = new Stuff();
    }

}




How do you think the output will look?



Every time a Stuff object is constructed, the constructor runs.

Counting Objects



Suppose we want to count each object that's created. We need to increment a variable every time we create a new Stuff object. If we want to do this in the class itself, how can we make the variable stick around from object to object? We need to declare it static so that it's part of the class, not part of any individual object.


public class Stuff {
    
    // Set count to zero initially.
    static int count = 0;
    
    public Stuff() {
        
        // Every time the constructor runs, increment count.
        count = count + 1;
        
        // Display count.
        System.out.println("Created object number: " + count);
    }
}





The static count variable is set to 0 at the instant it's created, right where it's declared. But every time a the constructor is invoked subsequently (by creating a new object in the 'main' method), it increments count.

So we are effectively keeping count of how many objects are created.

Even though count is part of the class, not part of the individual objects, nevertheless individual objects can still do stuff with it.

Care to take a guess what the output will look like now?



Assigning IDs to Objects



Now that we are counting objects, we can use the count to assign an ID to each object.

We can't use 'count' itself for the ID, because it changes every time a new object is created.

We need to create an instance (per-object) variable to store the ID. Then we can set the ID variable using 'count' in the constructor!

We'll also add a getId() method so that the 'main' method can get at the ID.



public class Stuff {
    
    // Set count to zero initially.
    static int count = 0;
    
    // Use this to store an ID for each object.
    int id;
    
    public Stuff() {
        
        // Every time the constructor runs, increment count.
        count = count + 1;
        
        // Set the object ID using count.
        id = count;
        
        // Now count can change but id will be unaffected.
    }
    
    // This just returns the ID.
    public int getId() {
        return id;
    }
}





Let's modify 'main' so that it retrieves and displays the ID of the second object it creates.

public class Application {
    
    public static void main(String[] args) {
        Stuff stuff1 = new Stuff();
        Stuff stuff2 = new Stuff();
        Stuff stuff3 = new Stuff();
        
        System.out.println("ID of object 2 is: " + stuff2.getId());
    }

}





You know what the output will be, right?



And of course, the ID of the first object will be 1, the ID of the third object 3, etc.

Each object has its own separate ID, which is set in the constructor using the static 'count' variable.

More? You Want More?



If you can follow this lot, you've got the hang of static variables. There's not a whole lot more to them. Later on you'll doubtless come across static initialization blocks and singleton objects, which won't even give you a headache now that you've got a solid grounding.