Static variables explained, in Java

Static variables, explained (using Java)

One of the more complicated concepts that beginning programmers have trouble grasping is static variables. This is in part because static variables work in a way that is quite opposite to how classes and Object-Oriented Programming (OOP) work.

Since examples work wonders in explaining concepts, here’s a use-case in Java that will help to illustrate the concept. Don’t code in Java? No problem. OOP concepts are (mostly) the same across programming languages.

An example problem

Consider this class:

public class BadGuy {
    private int health = 100;
    public int mana = 50;
    
    public BadGuy(int hp, int mp) {
        health = hp;
        mana = mp;
    }
    
    public void Damage(int amount) {
        health -= amount;
    }
}

Pretty standard Java class. Now, if we want to create instances of the BadGuy class, we will call the constructor using the new keyword.

public class MyCoolGame {
    public static void main(String[] args) {
        new BadGuy(50, 30); // Create bad guy with 50 HP and 30 Mana.
        new BadGuy(60, 20); // Create bad guy with 60 HP and 20 Mana.
    }
}

What if we want to call the Damage() function to reduce their health, or change their mana? One way is to store them in local variables:

public class MyCoolGame {
    public static void main(String[] args) {
        BadGuy badGuyA = new BadGuy(50, 30); // Create bad guy with 50 HP and 30 Mana.
        BadGuy badGuyB = new BadGuy(60, 20); // Create bad guy with 60 HP and 20 Mana.
    
        badGuyA.Damage(20); // Deals 20 damage to bad guy. Now he has 30 hp.
        badGuyB.Damage(10); // Deals 10 damage to bad guy. Now he has 50 hp.

        badGuyB.mana = 1; // Changes bad guy's mana to 1.
}

This way of doing things has a limitation though. If you call this in another method or class, you will not be able to access those references:

public class MyCoolGame {
    public static void main(String[] args) {
        BadGuy badGuyA = new BadGuy(50, 30); // Create bad guy with 50 HP and 30 Mana.
        BadGuy badGuyB = new BadGuy(60, 20); // Create bad guy with 60 HP and 20 Mana.
    
        another();
    }

    public static void another() {
        // Code fails because badGuyA and badGuyB are not accessible from another().
        // In other words, they are not in the scope of this function.
        badGuyA.Damage(20);
        badGuyB.Damage(10);
    }
}

Article continues after the advertisement:


Solving the problem with a static field

If we integrate a static List variable all into our BadGuy class, however, we can now access all the BadGuy instances from anywhere, because the all variable can be accessed from any class, in any method, with BadGuy.all.

Consider the scripts below:

public class BadGuy {
    private int health = 100;
    public int mana = 50;
    
    public static List<BadGuy> all = new List<BadGuy>();
    
    public BadGuy(int hp, int mp) {
        health = hp;
        mana = mp;
        
        // Automatically stores every instantiated BadGuy into the BadGuy.all array.
        all.add(this);
    }
    
    public void Damage(int amount) {
        health -= amount;
    }
}
public class MyCoolGame {
    public static void main(String[] args) {
        // Because the constructor automatically stores any new
        // instances of BadGuy into BadGuy.all, we don't have to
        // store the reference.
        new BadGuy(50, 30);
        new BadGuy(60, 20);
    
        BadGuy.all.get(0).Damage(10); // Deals damage to the first BadGuy we created.
        BadGuy.all.get(1).Damage(10); // Deals damage to the second BadGuy we created.

        another();
    }
    public static void another() {
        // We can access BadGuy.all from anywhere!
        BadGuy.all.get(0).Damage(15); // Deals damage to the first BadGuy we created.
        BadGuy.all.get(1).Damage(15); // Deals damage to the second BadGuy we created.
    }
}

Essentially, the difference between a static variable, and a regular ol’ instance variable (i.e. variables without the static modifier) is that static variables are accessed from the class, instead of being accessed from an instance. This makes static variables different from regular class variables in a few ways:

  • There is only 1 copy of each static variable, as opposed to regular class variables where each instance of the class will store a copy of the class variable (e.g. every BadGuy has its own health property).
  • All instances of the class share the static variable. Since there is only 1 copy of the static variable, if an instance changes the static variable’s value, the change will be reflected in all the other instances.
  • Static variables are “global” in scope. They can be accessed from anywhere in the program because class names can be accessed from anywhere in the program.

Conclusion

Did this short example help you understand what static variables are? Let us know in the comments below!


Article continues after the advertisement:


Leave a Reply

Your email address will not be published.