Static & private interface methods in Java
Helpers in interfaces; static ones are not inherited by implementers.
List.of(1, 2, 3) — wait, List is an interface. Since when can you call a method directly on an interface?Utilities that live on the interface
Since Java 8, an interface can have static methods, called on the interface name: Iface.method(). Examples: List.of(...) (Java 9), Map.entry(...), Comparator.naturalOrder(). They're handy factories that sit right next to the type they create.
interface Ids {
static String next() {
return "ID-7";
}
}
String id = Ids.next();Borrow through the class?
User implements Ids. What happens?
interface Ids {
static String next() { return "ID-7"; }
}
class User implements Ids { }
void main() {
System.out.println(User.next());
}ID-7Compile errornull
Show the answer
Static interface methods are not inherited by implementing classes — not through the class name, not through an instance. Ids.next() works; User.next() doesn't compile.
Private helpers (Java 9)
Two defaults doing similar work? Since Java 9 an interface may have private methods to share that code. Here a() returns [a] and b() returns [b], both through wrap.
interface Fmt {
default String a() { return wrap("a"); }
default String b() { return wrap("b"); }
private String wrap(String s) {
return "[" + s + "]";
}
}Implementers can't borrow private helpers
A private interface method is visible only inside the interface body. An implementing class that calls wrap() gets a compile error — private means private, even for the family.
class F implements Fmt {
String test() {
return wrap("x"); // error
}
}The full toolkit
An interface can now mix four kinds of methods: abstract — no body, implementers must provide one; default — has a body, inherited and overridable; static — called as Iface.m(), not inherited; private — a helper usable only inside the interface.
Factories on the type itself
Modern Java APIs lean on static interface methods: List.of, Map.of, Comparator.comparing, Path.of. Before Java 8, these had to live in separate helper classes like Collections and Paths, which made them harder to discover.
Key takeaways
- Call static interface methods as Iface.method()
- Static interface methods aren't inherited by implementers
- private methods are helpers visible only inside the interface
- Examples: List.of(), Map.entry(), Comparator.naturalOrder()
Paths.get() existed since Java 7 because interfaces couldn't hold static methods back then. Java 11 added Path.of() directly on the interface, and the JDK docs now recommend it instead.
Practice questions
What does this print?
interface Util {
static String tag() { return "util"; }
}
class Impl implements Util { }
void main() {
System.out.println(Impl.tag());
}- util
- Compile error
- null
- Throws NoSuchMethodError
Check your answer
Compile error. Static interface methods belong only to the interface. Impl.tag() doesn't compile; Util.tag() would.
What does this print?
interface Fmt {
default String a() { return wrap("a"); }
default String b() { return wrap("b"); }
private String wrap(String s) {
return "[" + s + "]";
}
}
class F implements Fmt { }
void main() {
System.out.println(new F().a() + new F().b());
}- [a][b]
- ab
- Compile error: private in interface
- [ab]
Check your answer
[a][b]. Since Java 9 interfaces may have private methods. Both defaults reuse wrap(), so the output is [a][b].