Back to Default & Static Methods in Interfaces
Q3Question 3 of 3

How are static methods in interfaces called?

Key Concepts
  • Interface static methods are called ONLY via InterfaceName.method(), never via an implementing class or instance.
  • Static methods are NOT inherited: implementing classes cannot call them using their own class name.
  • Static methods CANNOT be overridden: a class can define a method with the same name, but it is a separate method.
  • They replace the companion utility class pattern: Comparator.comparing() instead of ComparatorUtils.
  • Common uses: factory methods (List.of), utility functions (Predicate.not), and constants (Taxable.gstRate).
  • They keep related functionality together with the interface instead of scattering it across utility classes.
  • Java 9+ expanded this pattern: List.of(), Set.of(), Map.of() are all static methods on collection interfaces.

Definition

Interface static methods are called via InterfaceName.method() only, are not inherited by implementing classes, cannot be overridden, and replace companion utility classes.
  • Calling: static methods on interfaces are called exclusively via InterfaceName.method(), never via an implementing class or an instance reference.
  • Not inherited: if AccountService has a static method, SavingsAccountServiceImpl.method() does not compile.
  • Not overridable: a class can define a method with the same name, but it is a completely separate method, not an override.
  • Replaces utility classes: instead of Collections.sort() (utility class) and Collection (interface), Java 8 puts Comparator.comparing() and Predicate.not() directly on the interface.
  • Factory methods: List.of(), Map.of(), Set.of() (Java 9) are static methods on collection interfaces.
  • Keeps logic together: related functionality lives on the interface instead of being scattered across utility classes.

Think of the RBI (Reserve Bank of India) publishing a standard interest calculator on their website. Every bank in India can use the RBI calculator by visiting rbi.gov.in/calculator (InterfaceName.method()). But no bank can put that calculator on their own website and claim it as theirs (not inherited). HDFC cannot say HDFC.calculateInterest(); it must say RBI.calculateInterest(). The calculator belongs to RBI (the interface), not to any specific bank (implementing class).

Understanding the Concepts

How are static methods in interfaces called?

Static methods in interfaces were added in Java 8. They belong to the interface namespace and are not part of the implementing class's API.

What is the syntax and calling convention?

JAVA
package com.bank.service;

import java.math.BigDecimal;
import java.math.RoundingMode;

public interface InterestService {
    BigDecimal calculate(BigDecimal principal, int months);

    // Static: belongs to the INTERFACE
    static BigDecimal roundToPaisa(BigDecimal amount) {
        return amount.setScale(2, RoundingMode.HALF_UP);
    }

    static InterestService simpleInterest(BigDecimal annualRate) {
        return (principal, months) -> principal
            .multiply(annualRate)
            .multiply(BigDecimal.valueOf(months))
            .divide(BigDecimal.valueOf(12), 2, RoundingMode.HALF_UP);
    }
}
JAVA
// CORRECT: called via InterfaceName
BigDecimal rounded = InterestService.roundToPaisa(new BigDecimal("123.456"));
System.out.println(rounded); // 123.46

// WRONG: cannot call via implementing class
// class FDInterestService implements InterestService { ... }
// FDInterestService.roundToPaisa(...); // COMPILE ERROR!

// WRONG: cannot call via instance
// FDInterestService fd = new FDInterestService();
// fd.roundToPaisa(...); // COMPILE ERROR!

Why are static methods not inherited?

JAVA
package com.bank.core;

import java.math.BigDecimal;

interface Taxable {
    static BigDecimal gstRate() { return new BigDecimal("0.18"); }
}

class BrokerageService implements Taxable { }

public class StaticNotInherited {
    public static void main(String[] args) {
        // BrokerageService.gstRate(); // COMPILE ERROR: cannot find symbol
        System.out.println(Taxable.gstRate()); // Works: 0.18
    }
}
TEXT
0.18

Can static methods be overridden?

No. A class can define a method with the same name, but it is a completely separate method. The @Override annotation produces a compile error.

JAVA
package com.bank.core;

import java.math.BigDecimal;

interface Taxable {
    static BigDecimal gstRate() { return new BigDecimal("0.18"); }
}

class BrokerageService implements Taxable {
    // NOT an override: separate static method on the class
    // @Override // COMPILE ERROR if you try!
    static BigDecimal gstRate() { return new BigDecimal("0.12"); }
}

public class StaticNotOverridden {
    public static void main(String[] args) {
        System.out.println(Taxable.gstRate());          // 0.18 (interface)
        System.out.println(BrokerageService.gstRate()); // 0.12 (class's own)
    }
}
TEXT
0.18
0.12

How did this change the standard library?

| Before Java 8 | After Java 8+ |
|---------------|---------------|
| Collections.sort(list) | list.sort(comparator) (default) |
| Collections.unmodifiableList(list) | List.of(elements) (static, Java 9) |
| Manual Comparator creation | Comparator.comparing(Account::balance) (static) |
| Custom utility class | Predicate.not(Account::isDormant) (static) |

What are common use cases?

Factory methods like List.of(), Map.of(), and Set.of(). Utility functions like Comparator.comparing(), Predicate.not(), and Comparator.naturalOrder(). Constants like Taxable.gstRate(). Validation like AccountValidator.isValidIFSC(String code).

What are the rules and constraints?

Static methods cannot call instance methods or default methods on the interface because there is no instance. They can only use their parameters and other static methods. They cannot reference this or super.

What should a senior engineer know?

The pattern of putting static factory methods on interfaces continues to grow in Java. Java 9 added List.of(), Set.of(), Map.of(). Java 16 added Stream.toList(). This keeps related functionality together and eliminates the need for companion utility classes. In API design, prefer interface static methods over separate utility classes when the functionality is conceptually tied to the interface.

Visual Overview

DIAGRAM
  Static method on interface:
  ┌──────────────────────────────┐
  │ interface InterestService {   │
  │   static roundToPaisa(amt)   │ ← belongs HERE
  │ }                             │
  └──────────────────────────────┘
         │
         │  InterestService.roundToPaisa()  ← CORRECT
         │
  ┌──────────────────────────────┐
  │ class FDService              │
  │   implements InterestService │
  │                              │
  │   FDService.roundToPaisa()   │ ← COMPILE ERROR!
  │   (NOT inherited)            │
  └──────────────────────────────┘

  Before Java 8:           After Java 8:
  Collections.sort(list)   list.sort(cmp)         (default)
  ComparatorUtils.by(fn)   Comparator.comparing() (static)

Key Takeaway

Interface static methods are called exclusively via InterfaceName.method() and are not inherited by implementing classes. They cannot be overridden. If a class defines a method with the same name, it is a completely separate method, not an override. This is fundamentally different from default methods, which are inherited and can be overridden.

The practical impact is seen across the Java standard library. List.of(), Map.of(), and Set.of() replace Collections.unmodifiableList(). Comparator.comparing() and Comparator.naturalOrder() replace manual Comparator instantiation. Predicate.not() replaces verbose negation lambdas. The pattern keeps related functionality together on the interface itself rather than scattering it across utility classes.

In Rajesh's interest calculation service at National Bank of India, the InterestService interface has one abstract method (calculate) and two static methods (roundToPaisa and simpleInterest). Both are called via InterestService.methodName() by all implementing classes. Before Java 8, these would have been in a separate InterestUtils class.

Remember one sentence: interface static methods are called via InterfaceName.method(), are not inherited, cannot be overridden, and replace companion utility classes.

---

Share
Use ← → arrow keys to navigate