Java Article 23 - Static Fields

The term static in Java can be confusing so in this article I will try to clarify it as much as possible, or at least provide a new perspective on the topic. The term static can apply to fields, methods, and initialization blocks but in this article we are just talking about static fields.

When most people think of a variable in Java they think of something like:

public class someClass { int myInt; }

This is an example of an instance variable. myInt is meant to be used by an object and cannot be used by a class that is not instantiated.

A static field is a variable that is associated with a class and it is a single location in memory shared between subclasess and instances (objects) of this class.

Below are a couple of examples of static fields:

public class someOtherClass
	private static int someInt;
	public static String someString = "this is just some string';

Static fields have the modifier "static" included as shown. The static modifier tells you (and the compiler) that these variables are static fields and not instance variables.

Static fields were created to provide a variable that works differently from instance variables. An instance variable only exits in one particular object and can only be referenced from an object. Here, referenced means used by, changed, or to retrieve the value of, etc. An instance variable can not be referenced from a class.

A common IDE error message seen in Java is "Cannot make a static reference to the non-static field." You get this error when you try to reference an instance variable from a class (a stand-alone class that in not instantiated into an object).

So all this means is that static fields do not require any objects to exist for the static fields to be referenced. So with static fields you can write and use classes that never get instantiated into objects. One use of a class with static fields (and static methods which we will talk abut in the next article) would be a class that does a calculation and returns a value. You do not need an object to do this and you save a little memory and a few lines of code by not instantiating an object.

The above could take the form of:

public class ClassA 
	public static void main(String[] args) 
		ClassA classAObject = new ClassA();
	public ClassA()
		//Since we are calling a class and not an object
		//we have to use the Class's name: ClassB
...then our class with the static method
public class ClassB 
	public static float multiplyTwoValues(float firstNumber, 
             float secondNumber)
		//local variable
		float returnValue = firstNumber * secondNumber;
		return returnValue;

Ok all that is great, but maybe you are reading this article because you were already a bit uncomfortable with the term static, and the whole static concept (or perhaps you are stuck waiting at the dentist's office and you don't want to read a Highlights magazine from 1974.)

There are several things about static fields that can casue some confusion:

In Java, the term static field has several synonyms. Static fields can also be called:

  • fields
  • class fields
  • static variables
  • class variables
You can probably get away with calling them any of the above without sounding dumb. I prefer to keep the word static or class in there to remind people the variable applies to the class. I also like the world variable over field since it uses the same naming scheme as other variables (e.g. instance variables and methods variables).

The term static is also misleading:

In English, the word static typically is thought to mean "lacking in change, being fixed, or immobile." Programming language architects have come up with some great usages of English words in programming but this is not one of the best.

The value of a static field can be changed. In fact, both objects and classes can reference and change static fields. One cool thing about static fields is that they are easily referenced/changed by classes and objects.

I tend to think of the modifier static as meaning "it is a single fixed memory location that is held there for widespread use."

It is a bit like a dry-erase board in the front of a classroom. If the instructor or any student make a change to it, all other students in that class now have the new value for dryEraseBoad. dryEraseBoad is one variable that is shared by all members of the class.

On the other hand, an instance variable is like a student's notebook. Individual notebooks are owned by each of the students and what a student writes in their individual notebook is unique to that particular notebook and does not impact any of the other notebooks.

So in today's example there is a main class that acts on a superclass and a subclass. The super and subclasses both manipulate a class variable (also know as the field or static field) and an instance variable. You can see they all share the same value for the class variable and then each have their own value for the instance variable.

public class MainClass 
	//this is just here to show we can't reference it from the static method:
        int myInt; 
	public static void main(String[] args) 
		//Note: you can't reference an instance variable from a class:
		//TheSuperClass.objectName = "";
		//nor can you reference the above instance variable:
		//myInt = 5;
		System.out.println("Note: Even before the object is " +
				"instantiated we can reference " +
				"\nour static " +
				"field, aClassVariable:");
		System.out.println("aClassVariable = " 
				+ TheSuperClass.aClassVariable);
		TheSuperClass superClassObject 
		= new TheSuperClass("superClassObject");
		TheSubClass subClassObject1 
		= new TheSubClass("subClassObject1");
		TheSubClass subClassObject2 
		= new TheSubClass("subClassObject2");
		//now we can access the variables
		//Class variables should be referenced by the class name
		System.out.println("\nNote: Every instance of TheSuperClass" +
				" and its subclasses" +
				"\nshare our class variable, which is in " +
				"one fixed location in memory:");
		System.out.println("TheSuperClass.aClassVariable = " 
				+ TheSuperClass.aClassVariable);
		System.out.println("TheSubClass.aClassVariable = " 
				+ TheSubClass.aClassVariable);

Then our super class:

public class TheSuperClass 
	public static String aClassVariable = "This is the static " +
			"field declared in the superclass"; 
	public String aInstanceVariable = "This is the " +
	"string declared in the superclass"; 
	String objectName;
	public TheSuperClass(String name) 
		this.objectName = name;
		System.out.println("\n" + objectName + " has been created");		
	public void displayTheClassVariable()
		System.out.println("\n" + objectName 
			+ ": aClassVariable = " + aClassVariable);

	public void displayTheInstanceVariable() 
			+ ": aInstanceVariable = " + aInstanceVariable);

Then finally we have our subclass:

public class TheSubClass extends TheSuperClass
	public TheSubClass(String name)
		System.out.println(objectName + ": aClassVariable = " 
				+ aClassVariable);
		System.out.println(objectName + ": is now " +
				"modifying aClassVariable...");
		aClassVariable = aClassVariable + " (modified by " 
		+ objectName + ")";
		System.out.println(objectName + ": aClassVariable = " 
				+ aClassVariable);
		//now we modify aInstanceVariable
		System.out.println("\n" + objectName 
				+ ": aInstanceVariable = " 
				+ aInstanceVariable);
				+ ": is now modifying " +
		aInstanceVariable = aInstanceVariable 
		+ " (modified by " + objectName + ")";
		System.out.println(objectName + ": aInstanceVariable = " 
				+ aInstanceVariable);

Another use for static variables is to create constants, which I will cover in the next article.