Interface constants in Java
Fields are implicitly public static final.
int MAX = 10; inside an interface. Java quietly rewrites it into something much stricter. What did it add?Three invisible keywords
Every field in an interface is implicitly **public static final**. public: anyone can read it. static: one shared copy, not one per object. final: it can never change. So interfaces can't hold per-object state — only constants.
interface Limits {
int MAX_USERS = 100;
// = public static final int MAX_USERS
}Try to bump it
What happens here?
interface Limits {
int MAX = 10;
}
void main() {
Limits.MAX++;
System.out.println(Limits.MAX);
}1110Compile error
Show the answer
MAX is implicitly final, so ++ (an assignment in disguise) is rejected by the compiler. Interface constants are frozen forever.
Born with a value
Because the field is final and interfaces have no constructors, it must be initialized right where it is declared. int MAX; alone is a compile error. A constant may be built from other constants, like BIG = SMALL * 5.
interface Sizes {
int SMALL = 2;
int BIG = SMALL * 5; // 10
// int MAX; <- compile error
}Reading the constants
Outside code writes Sizes.BIG. A class that implements the interface inherits the constants and can use the bare names. Here total() returns 10 - 2 = 8.
class Cup implements Sizes {
int total() {
return BIG - SMALL;
}
}The constant-interface anti-pattern
Implementing an interface *just* to use its constants without a prefix is a classic mistake. implements is a public promise: your class — and every subclass — now permanently is-a constants holder, leaking an implementation detail into its type. Put constants in a final class with a private constructor, or in an enum.
Spotted in the JDK
Old JDK code made this mistake: ObjectOutputStream implements the constants-only interface ObjectStreamConstants, and it can never be undone without breaking users. Modern code keeps constants in a final class like HttpHeaders or uses enums for related choices.
Key takeaways
- int MAX = 10; in an interface means public static final int MAX = 10;
- Must be initialized at the declaration
- Read it as Limits.MAX (implementers can also use MAX directly)
- Constants-only interfaces are an anti-pattern; prefer a final class or enum
Compile-time constants are copied into every class that uses them. Change an interface constant without recompiling those classes, and they keep using the OLD value.
Practice questions
What does this print?
interface Config {
int RETRIES = 3;
}
void main() {
Config.RETRIES = 5;
System.out.println(Config.RETRIES);
}- 5
- 3
- Compile error
- Throws UnsupportedOperationException
Check your answer
Compile error. RETRIES is implicitly final, so assigning to it is rejected at compile time.
Does this interface compile?
interface Limits {
int MAX;
}- No: MAX must be initialized
- Yes: MAX defaults to 0
- Yes: each implementing class sets MAX
- Only if the interface is also declared abstract
Check your answer
No: MAX must be initialized. Interface fields are final constants, and a final field with no initializer is never assigned — so it's a compile error.