JB Header

Static vs Instance Methods in Java

Introduction So far, nearly every method in this series has been declared static, because that let us call it straight from main(). But most methods in real Java programs are instance methods, which belong to objects. This tutorial explains static vs instance methods in Java. We will start with what each kind of method is, and how each is called. We will then see what each kind can access - and the most common compile error beginners meet: "non-static method cannot be referenced from a static context". Next we will understand why main() is static. Lastly, we will see when to use each kind, with typical examples from the Java library.

(Note - This tutorial builds on Java MethodsClick to read tutorial: Java Methods: Defining, Calling and Returning Values, and on static and instance variables from Variables in JavaClick to read tutorial: Variables in Java: Declaration, Initialization and Scope.) Static methods and instance methods
  • Static methods (class methods) are declared with static. They belong to the class itself, and are called on the class name - Math.sqrt(16), Integer.parseInt("42"). No object is needed.
  • Instance methods are declared without static. They belong to each object (instance) of the class, and are called on an object - name.length(), list.add("Tom"). They work with that particular object's data.
The program below defines a simple bank account class with both kinds of method.
A class with static and instance methods
//BankAccount.java
public class BankAccount {
  static double interestRate = 0.04;    // static variable - shared by all accounts
  static int accountsOpened = 0;

  String owner;                         // instance variables - one copy per account
  double balance;

  BankAccount(String owner, double balance) {
    this.owner = owner;
    this.balance = balance;
    accountsOpened++;
  }

  void deposit(double amount) {         // instance method - works on THIS account
    balance += amount;
  }

  double yearlyInterest() {             // instance method - uses this account's balance
    return balance * interestRate;
  }

  static void setInterestRate(double rate) {    // static method - affects the whole class
    interestRate = rate;
  }

  static double toPercent(double rate) {        // static utility - needs no account at all
    return rate * 100;
  }

  public static void main(String[] args) {
    BankAccount toms = new BankAccount("Tom", 1000);
    BankAccount harrys = new BankAccount("Harry", 2500);

    toms.deposit(500);                                   // called on an object
    System.out.println(toms.owner + ": " + toms.balance + ", interest " + toms.yearlyInterest());
    System.out.println(harrys.owner + ": " + harrys.balance + ", interest " + harrys.yearlyInterest());

    BankAccount.setInterestRate(0.05);                   // called on the class
    System.out.println("New rate: " + BankAccount.toPercent(interestRate) + "%");
    System.out.println(toms.owner + "'s interest now " + toms.yearlyInterest());
    System.out.println("Accounts opened: " + BankAccount.accountsOpened);
  }
}
 OUTPUT of the above code
Tom: 1500.0, interest 60.0
Harry: 2500.0, interest 100.0
New rate: 5.0%
Tom's interest now 75.0
Accounts opened: 2
Explanation of the code
  • new BankAccount(...) creates an object, and the constructor - the method-like block named after the class - sets its initial data. Classes, objects and constructors are covered in detail later in this series.
  • toms.deposit(500) changed only Tom's balance. Each instance method call works on the object it was called on - inside the method, balance means that object's balance.
  • setInterestRate() changed the static interestRate, which all accounts share, so Tom's interest changed too.
  • toPercent() uses only its parameter. It needs no account, so it is naturally static.
What each kind of method can access
  • An instance method can use everything - the object's instance variables and instance methods, this, and also the class's static variables and static methods.
  • A static method can use static variables and other static methods directly. It cannot use instance variables, instance methods or this directly - because there is no object to use them on. Which account's balance would a static method mean?
Breaking this rule is one of the first compile errors every Java beginner sees -
Calling an instance method from a static method
//StaticContext.java
public class StaticContext {
  int count = 0;

  void increment() {
    count++;
  }

  public static void main(String[] args) {
    increment();
    System.out.println(count);
  }
}
 OUTPUT on compiling the above code
StaticContext.java:10: error: non-static method increment() cannot be referenced from a static context
    increment();
    ^
StaticContext.java:11: error: non-static variable count cannot be referenced from a static context
    System.out.println(count);
                       ^
2 errors
main() is static, so it has no object of which to increment count. There are two fixes: create an object and call the method on it, or - if the method does not need any object's data - make it static.
Two ways to fix the static context error
//StaticContextFixed.java
public class StaticContextFixed {
  int count = 0;

  void increment() {
    count++;
  }

  static int square(int x) {          // needs no object: make it static
    return x * x;
  }

  public static void main(String[] args) {
    StaticContextFixed counter = new StaticContextFixed();   // fix 1: create an object
    counter.increment();
    counter.increment();
    System.out.println("count = " + counter.count);
    System.out.println("square(9) = " + square(9));          // fix 2: a static method
  }
}
 OUTPUT of the above code
count = 2
square(9) = 81
Why main() is static When you run java MyProgram, no objects exist yet. The JVM needs a method it can call without first creating an object - and without knowing how to construct one. That is exactly what a static method is. So main() is public static void main(String[] args), and real programs use it as a starting point which creates the first objects and calls their instance methods, as the bank account example did.

Note - Java 25 also allows an instance main() in small programs, in which case the launcher creates the object for you - see the Hello World tutorialClick to read tutorial: Java Hello World Program Explained Line by Line. The traditional static main() remains the standard form. When to use static and when to use instance methods
Static methodInstance method
Belongs toThe classEach object
Called asClassName.method()object.method()
Can use instance data and this?No (only through an object)Yes
Can use static data?YesYes
Can be overridden?No - only hiddenYes
Typical useUtilities working only on their parameters; factory methods; main()Behaviour that uses or changes an object's state
Library examplesMath.max(), Integer.parseInt(), Arrays.sort(), List.of()"text".length(), list.add(), sb.append()

A simple test: if a method needs data that belongs to a particular object, make it an instance method. If it works only with its parameters (and perhaps constants), it can be static. Most methods in an object-oriented program are instance methods; static methods are best kept for helpers and factories.

Note - Java lets you call a static method through an object variable - toms.toPercent(0.05) - but this is misleading, as the object is ignored. Always call static methods on the class name. Summary In this tutorial we first saw that static methods belong to the class and are called on the class name, while instance methods belong to objects and work with each object's own data. We then saw that instance methods can use everything, but static methods cannot use instance variables, instance methods or this directly - and fixed the "non-static method cannot be referenced from a static context" error in two ways. Next we understood why main() is static. Lastly, we compared the two kinds of methods, and saw when to use each. This completes the Beginner level of the Java Fundamentals series - well done! You can revisit any topic from the list below.