The Static Keyword

When we define a class, we typically want each instance of the class to have a copy of each of the fields.  For example, when an instance of the Box class is created, the instance contains its own height. width , and length variables.  If every instance of the Box class shared the same three variables, then we’d essentially limit ourselves to a single box.

There are cases, however, when we don’t need multiple instances of a field or method in a class, one instance will do.  Take the Math class for example.  When we try to create an instance of the class we receive a compile error telling us the Math constructor is private.  That implies the Math class can’t be instantiated.  If we can’t create an instance of the class, how do we access the 2 fields and 73 methods in the class and where do they reside?  The answer is found by looking at the modifiers for each field and method.

Each field and method in the Math class is static.  When a field or constructor is static then no more than a single instance of the field or method exists in memory at any given time.  We access the single instance of the field or method using the name of the class and the dot operator or if the class is instantiable by a reference to an instance of the class and the dot operator.  For example, to access the PI field in the Math class, since the Math class is not instantiable, we write the following:

double circumference = 2 * Math.PI * radius;

Static fields that hold constants are usually given names that contain all caps and words separated by underscore characters as shown above with the field named PI in the Math class.

We can access static methods by using the class name, dot operator, and name of the method as shown below. Here we call the static method named min found in the Math class.

int minimum = Math.min(score1, score2);

Static Fields

As mentioned above, only one instance of a static field exists even though there may be multiple instances of the class that defines the static field.  In other words, if multiple instances of a class exist, then all of the instances share the static field variables.  This implies that if the static field is not final, each of the instances can modify the field’s value.  Let’s take a look at an example.  Below is a class named Foo with two fields. One of them, a, is static, and the other one, b, is not.

public class Foo {
    private static String a;
    private int b;

    public Foo(String a, int b) { 
        this.a = a; 
        this.b = b;
    }

    public static String getA() { return a; }
    public int getB() { return b; }
}

When we create two instances of Foo, both share the field a and both will have their own copies of b.

public class Driver {
    public static void main(String ... args) {
        Foo f = new Foo("one", 1);
        System.out.println(f.getA() + ", " + f.getB());     // prints one, 1
        System.out.println(Foo.getA() + ", " + f.getB());   // prints one, 1

        Foo g = new Foo("two", 2);
        System.out.println(g.getA() + ", " + g.getB());     // prints two, 2
        System.out.println(Foo.getA() + ", " + f.getB());   // prints two, 1
    }
}

Static Blocks

A static block is a block of code that is executed exactly once when the class is loaded, before any instances of the class is created.  The syntax for a static block is shown below.

public class Foo {     
    ...     
    
    static { 
        ...
    }

    public Foo() { 
         ...
    } 
}

Static Method and Static Block Limitations

Static method and static blocks have limitations.

  • They cannot directly call non-static methods
  • They cannot access non-static fields
  • They cannot refer to this (an instance) or super.

© 2017 – 2019, Eric. All rights reserved.