Verified for the 2025 AP Computer Science A exam•Citation:
In Java, not everything belongs to individual objects. Sometimes, we need data or behaviors that are shared across all instances of a class or that exist even without any instances at all. This is where the static
keyword comes in. Static variables and methods belong to the class itself rather than to any specific object. They provide a way to define class-level properties and behaviors that can be accessed without creating an instance. In this section, we'll explore how static members work, when to use them, and how they differ from their non-static counterparts.
Static variables (also called class variables) are:
static
keywordpublic class School { // Instance variable - each School object has its own name private String name; // Static variable - shared by all School objects private static int totalSchools = 0; public School(String name) { this.name = name; totalSchools++; // Increment the shared counter } public static int getTotalSchools() { return totalSchools; } }
Static variables can be designated as either public
or private
:
public class MathConstants { // Public static variable - accessible from any class public static final double PI = 3.14159265358979323846; // Private static variable - accessible only within this class private static int calculationCount = 0; }
private
to maintain encapsulationpublic
, consider making it final
(constant)Static variables are accessed using the class name and dot operator, since they are associated with a class, not objects:
// Accessing a public static variable double circleArea = Math.PI * radius * radius; // Accessing a static variable through a static method int schoolCount = School.getTotalSchools();
Unlike instance variables, which require an object reference followed by the dot operator, static variables are used with the class name:
// CORRECT: Using class name to access static variable int count = Counter.getCount(); // INCORRECT: Using an object to access static variable // (This works but is discouraged as it's confusing) Counter c = new Counter(); int count = c.getCount();
Static methods are:
static
keyword in the headerthis
referencepublic class MathHelper { // Static method - belongs to the class public static int square(int number) { return number * number; } // Static method with multiple parameters public static double average(double a, double b) { return (a + b) / 2; } }
Static methods are called using the class name:
// Calling a static method int squared = MathHelper.square(5); // Returns 25 // Using multiple static methods together double avg = MathHelper.average(3.5, 7.5); // Returns 5.5
Static methods cannot:
this
referencepublic class Example { private int instanceValue = 10; private static int staticValue = 20; // This works - static method accessing static variable public static void staticMethod() { System.out.println(staticValue); // ERROR: Cannot access instance variable // System.out.println(instanceValue); // ERROR: Cannot use this reference // System.out.println(this.staticValue); // ERROR: Cannot call non-static method // nonStaticMethod(); } public void nonStaticMethod() { // Non-static methods can access both static and instance members System.out.println(instanceValue); System.out.println(staticValue); staticMethod(); // Can call static methods } }
Static methods are perfect for utility functions that don't require object state:
public class StringUtils { public static boolean isEmpty(String str) { return str == null || str.trim().length() == 0; } public static String reverse(String str) { if (str == null) return null; return new StringBuilder(str).reverse().toString(); } }
Static variables are useful for tracking class-wide information:
public class User { private String username; private static int userCount = 0; public User(String username) { this.username = username; userCount++; } public static int getUserCount() { return userCount; } }
Static final variables are ideal for constants:
public class GameSettings { public static final int MAX_PLAYERS = 4; public static final int STARTING_LIVES = 3; public static final double GRAVITY = 9.8; }
Static methods that create and return objects of the class:
public class Color { private int r, g, b; private Color(int r, int g, int b) { this.r = r; this.g = g; this.b = b; } // Factory methods public static Color red() { return new Color(255, 0, 0); } public static Color green() { return new Color(0, 255, 0); } public static Color blue() { return new Color(0, 0, 255); } public static Color custom(int r, int g, int b) { return new Color(r, g, b); } }
Static Methods | Instance Methods |
---|---|
Declared with static keyword | No static keyword |
Belong to the class | Belong to objects |
Called using class name | Called using object reference |
Cannot access instance variables | Can access instance variables |
Cannot use this reference | Can use this reference |
Can only call other static methods directly | Can call both static and instance methods |
Exist even without objects | Require an object to be called |
The most well-known static method in Java is the main
method:
public class HelloWorld { public static void main(String[] args) { System.out.println("Hello, World!"); } }
The main
method must be static because it's the entry point of the program and is called before any objects are created.
Here's a complete example showing how static and instance members interact:
public class BankAccount { // Instance variables - unique to each account private String accountNumber; private double balance; // Static variables - shared across all accounts private static double interestRate = 0.02; // 2% private static int accountsCreated = 0; // Constructor public BankAccount(String accountNumber, double initialBalance) { this.accountNumber = accountNumber; this.balance = initialBalance; accountsCreated++; } // Instance methods - operate on a specific account public void deposit(double amount) { if (amount > 0) { balance += amount; } } public void withdraw(double amount) { if (amount > 0 && amount <= balance) { balance -= amount; } } public void addInterest() { // Instance method using static variable balance += balance * interestRate; } public double getBalance() { return balance; } // Static methods - operate at the class level public static void setInterestRate(double newRate) { if (newRate >= 0) { interestRate = newRate; } } public static double getInterestRate() { return interestRate; } public static int getAccountsCreated() { return accountsCreated; } }
// Set class-wide interest rate BankAccount.setInterestRate(0.03); // 3% // Create account instances BankAccount account1 = new BankAccount("A001", 1000); BankAccount account2 = new BankAccount("A002", 2000); // Get information about the class System.out.println("Accounts created: " + BankAccount.getAccountsCreated()); // 2 System.out.println("Current interest rate: " + BankAccount.getInterestRate()); // 0.03 // Operate on specific accounts account1.deposit(500); account1.addInterest(); // Uses the static interest rate System.out.println("Account 1 balance: " + account1.getBalance()); // 1545.0
public
or private
this
referencemain
method must be static because it runs before any objects are created