Lecture 15 Static and Final

Joseph Haugh

University of New Mexico

Free Recall

  • Get out a sheet of paper or open a text editor
  • For 2 minutes write down whatever comes to mind about the last class
    • This could be topics you learned
    • Questions you had
    • Connections you made

Review: Classes and Objects

  • A class is a blueprint, an object is an instance built from it
  • Classes have fields (data), constructors (setup), and methods (behavior)
  • Each object gets its own copy of the fields
  • Use new to create objects, dot notation to access fields and methods
  • private fields + public methods = encapsulation

Review: A Class at a Glance

class Point {
    private int x;
    private int y;

    public Point(int x, int y) {
        this.x = x;
        this.y = y;
    }

    public int getX() { return x; }
    public int getY() { return y; }

    public String toString() {
        return "(" + x + ", " + y + ")";
    }
}
  • this distinguishes the field from the parameter when names clash

Today’s Topics

  • The final keyword: locking values so they can’t be changed
  • The static keyword: things that belong to the class, not to any object

The final Keyword

  • final means: once set, cannot be reassigned
  • You can apply it to:
    • Local variables
    • Method parameters
    • Fields (instance variables)
  • Think of it as a write-once lock

final Local Variables

void main() {
    final int MAX = 100;
    IO.println(MAX); // 100

    MAX = 200; // COMPILE ERROR: cannot assign a value to final variable MAX
}
  • Once assigned, the variable is frozen
  • Useful for constants, values you never want to accidentally change

final Fields

  • Fields can also be marked final
  • They must be assigned exactly once, inside the constructor
class Circle {
    private final double radius;

    public Circle(double radius) {
        this.radius = radius; // assigned here, and never again
    }

    public double area() {
        return Math.PI * radius * radius;
    }
}

final Fields

void main() {
    Circle c = new Circle(5.0);
    IO.println(c.area()); // 78.53...

    c.radius = 10.0; // COMPILE ERROR: radius is private AND final
}
  • A final field communicates: this value defines the object and will never change
  • Great for things like a person’s ID number, a circle’s radius, etc.

final Parameters

  • You can also mark method parameters as final
double calculateTax(final double income) {
    income = 0; // COMPILE ERROR: cannot assign a value to final variable income
    return income * 0.25;
}
  • Less common, but useful when you want to make it clear the parameter shouldn’t be modified inside the method

final Arrays: The Gotcha

  • You might think final on an array means the array is completely frozen
  • It doesn’t.
  • final only locks the variable, you cannot reassign it to a new array
  • But you can still change the contents of the array!

final Arrays: Example

void main() {
    final int[] scores = {10, 20, 30};

    // This is FINE, changing the contents
    scores[0] = 99;
    IO.println(scores[0]); // 99

    // This is a COMPILE ERROR, reassigning the variable
    scores = new int[]{1, 2, 3};
}

final Arrays: Visualized

final int[] scores = {10, 20, 30};
  • final locks the arrow, scores must always point to this array
  • The arrow cannot be redirected to a different array
scores -> [ 10 | 20 | 30 ]
              ^
        contents are NOT locked
  • final != immutable. If you want truly immutable data you need other tools (not covered today).

When to Use final

Situation Use final?
A constant value that never changes (e.g., MAX_SIZE) Yes
A field that is set once and defines the object (e.g., id) Yes
A regular variable that might change later No
An array whose reference shouldn’t change Yes, but remember contents can still change

The static Keyword

  • Everything we’ve seen on a class so far belongs to individual objects
    • Each Point has its own x and y
    • Each BankAccount has its own balance
  • Sometimes you want something that belongs to the class itself, not to any one object
  • That’s what static is for

Static Fields

  • A static field is shared across all objects of that class
  • There is only one copy, no matter how many objects you create
class Counter {
    private static int count = 0; // shared by ALL Counter objects
    private int id;

    public Counter() {
        count++;
        this.id = count;
    }

    public static int getCount() { return count; }
    public int getId()           { return id; }
}

Static Fields: Example

void main() {
    Counter a = new Counter();
    Counter b = new Counter();
    Counter c = new Counter();

    IO.println(a.getId()); // 1
    IO.println(b.getId()); // 2
    IO.println(c.getId()); // 3

    IO.println(Counter.getCount()); // 3
}
  • count is one variable shared by all three objects
  • Notice we call Counter.getCount() using the class name, not an object

Static Methods

  • A static method belongs to the class, not to any object
  • It has no this, it cannot access instance fields or instance methods
  • Called using the class name: ClassName.methodName()
  • You’ve already used static methods!
Math.sqrt(25.0)   // Math is a class; sqrt is a static method
Math.abs(-5)
Math.max(3, 7)

Defining a Static Method

class MathUtils {
    public static int square(int x) {
        return x * x;
    }

    public static boolean isEven(int n) {
        return n % 2 == 0;
    }
}
void main() {
    IO.println(MathUtils.square(5));   // 25
    IO.println(MathUtils.isEven(4));   // true
    IO.println(MathUtils.isEven(7));   // false
}
  • No object needed, just use the class name

Static vs. Instance: Side by Side

Instance method

class Circle {
    private double r;

    public Circle(double r) {
        this.r = r;
    }

    // Needs an object, 
    // uses field r
    public double area() {
        return Math.PI * r * r;
    }
}
Circle c = new Circle(5.0);
c.area(); // called on an object

Static method

class MathUtils {

    // No object needed, uses only params
    public static double circleArea(double r) {
        return Math.PI * r * r;
    }
}
// called on the class
MathUtils.circleArea(5.0);

When to Use Static

  • Use static when the method or field does not depend on any object’s state
    • Utility / helper methods (Math.sqrt, converters, validators)
    • Constants shared across all objects (Math.PI, MAX_SIZE)
    • Counters or state shared across all instances
  • Do not use static when:
    • The method reads or writes instance fields
    • The behavior should differ per object
    • You need this

A Common Mistake

class Dog {
    private String name;

    public Dog(String name) {
        this.name = name;
    }

    // BUG: static method trying to use an instance field
    public static void bark() {
        IO.println(name + " says: Woof!"); // COMPILE ERROR
    }
}
  • static methods have no this, they can’t see name
  • Fix: either remove static, or pass name as a parameter

Static Constants

  • A common pattern is public static final for class-level constants
class Circle {
    public static final double PI = 3.14159265358979;
    private double radius;

    public Circle(double radius) {
        this.radius = radius;
    }
    public double area() {
        return PI * radius * radius;
    }
}
  • static: one copy for the class, not per object
  • final: value can never be changed
  • public: anyone can read it

static final vs. instance final

static final instance final
How many copies? One, shared by all objects One per object
Example Math.PI, MAX_SIZE a person’s unique ID
Accessed via Class name Object reference
Set when? At declaration In the constructor

Summary

final

  • Prevents reassignment of a variable or field
  • Field must be set in the constructor (and only once)
  • final array: reference is locked, contents are not
  • Use for constants and fields that define an object

static

  • Belongs to the class, not any object
  • No this cannot access instance fields
  • Call with ClassName.method() or ClassName.field
  • Use for utilities and shared data, avoid when you need per-object behavior