The <code>public</code> Access Modifier in Java
public is the broadest access modifier in Java. Any public class, method or field is visible from anywhere that can see the class. Every public member is a commitment β callers will use it, and future changes become breaking changes.
When to use it
- Your class's deliberate API β methods callers need.
- Constants exposed across packages (
public static final). - The main entry point (
public static void main). - Classes that other packages or other modules must import.
The one-public-top-level-class-per-file rule
// File: Foo.java
public class Foo { ... } // β
file name matches class name
class Bar { ... } // β
package-private companion
public class Baz { ... } // β compile error β only one public top-level per file
Every public symbol is a promise
Once a method, field or class is public and released, you can't rename or remove it without breaking callers. Changes to parameter types, return types or exceptions are all breaking. Treat the public surface as a contract.
Deliberate API design
public class UserService {
public Optional<User> findById(long id) { ... } // public β deliberate API
public void register(User u) { ... }
User loadFromCache(long id) { ... } // package-private β helper for tests
private Cache cache() { ... } // private β internal
}
Modules β a second layer
A class can be public but its package may not be exported by its module (module-info.java). In that case it's only visible inside the module. Useful for library authors who want a tiny public surface while still using public internally.
Common mistakes
- Making everything
publicβ the maintenance burden is enormous. Start tight. - Public fields β use private + accessor, or a record.
- Public helper classes that leak internals β if it's only used by one class, make it a nested
privateclass.
Related
Pillar: Java access modifiers. See also private, protected.