Lesson Completion
Back to course

Access Modifiers Comparison: The Ultimate Decision Guide

Beginner
10 minutesβ˜…4.8JavaPlay to Learn

1. The Hook (The "Byte-Sized" Intro)

In a Nutshell: Choosing the right access modifier is critical for API design, maintainability, and security. Use private for implementation details, default for package-internal helpers, protected for extension points, and public for stable APIs. Follow the Principle of Least Privilegeβ€”start restrictive, widen only when needed.

Think of Facebook privacy settings: "Only Me" (private), "Friends" (default), "Friends of Friends" (protected), "Public" (public). You control who sees what!


2. Conceptual Clarity (The "Simple" Tier)

πŸ’‘ The Analogy: The Hotel Access

  • Private: Your room (only you)
  • Default: Hotel floor (guests on your floor)
  • Protected: Hotel + sister hotels (guests in the hotel chain)
  • Public: Hotel lobby (anyone)

3. Technical Mastery (The "Deep Dive")

Complete Comparison Table

Featureprivatedefaultprotectedpublic
VisibilityClass onlyPackagePackage + SubclassesEverywhere
Keywordprivate(none)protectedpublic
Use CaseImplementationInternal APIExtension pointsPublic API
Can Change?Yes (safe)RiskyVery riskyNever (breaking)
Top-level Class?❌ Noβœ… Yes❌ Noβœ… Yes

Decision Matrix

graph TD Q1{Is it part of public API?} Q1 -- No --> Q2{Need subclass access?} Q1 -- Yes --> PUB[public] Q2 -- No --> Q3{Need package access?} Q2 -- Yes --> PROT[protected] Q3 -- No --> PRIV[private] Q3 -- Yes --> DEF[default] style PRIV fill:#D32F2F style DEF fill:#F57C00 style PROT fill:#2E7D32 style PUB fill:#2E7D32

4. Interactive & Applied Code

java
// Good Example: Proper Access Levels public class BankAccount { // public: API class private double balance; // private: implementation detail private String accountNumber; // private: sensitive data BankAccount(String number) { // default: package-only constructor this.accountNumber = number; this.balance = 0; } public void deposit(double amount) { // public: API method if (amount > 0) { balance += amount; logTransaction("deposit", amount); // private method } } public double getBalance() { // public: API method return balance; } protected void validateTransaction(double amount) { // protected: for subclasses if (amount < 0) throw new IllegalArgumentException("Negative amount"); } private void logTransaction(String type, double amount) { // private: internal System.out.println(type + ": $" + amount); } } class SavingsAccount extends BankAccount { SavingsAccount(String number) { super(number); } public void addInterest(double rate) { double interest = getBalance() * rate; validateTransaction(interest); // βœ… Can access protected method deposit(interest); } }

5. The Comparison & Decision Layer

When to Use Each

ScenarioModifier
FieldsAlmost always private
Getters/Setterspublic (if needed)
Utility methods (package)default
Template methodsprotected
API methodspublic
Constructors (framework use)Often protected or default

Best Practices

  1. Start with private β†’ widen only if needed
  2. Never make fields public (use getters/setters)
  3. Use default for package-internal utilities
  4. Use protected for extension points (Template Method pattern)
  5. Mark public APIs clearly (documentation, @API annotation)

6. The "Interview Corner" (The Edge)

The "Killer" Interview Question: "Why should you never make instance variables public?" Answer:

  1. Breaks encapsulation: External code directly accesses internals
  2. No validation: Can't enforce invariants (e.g., age > 0)
  3. Inflexible: Can't change implementation without breaking clients
  4. Thread-safety: Can't synchronize access

Always use private fields + public getters/setters, even if "simple"β€”you might need validation/logging later!

Real-World Example

java
// ❌ BAD public class User { public String email; // Anyone can set invalid email! } // βœ… GOOD public class User { private String email; public void setEmail(String email) { if (!email.contains("@")) { throw new IllegalArgumentException("Invalid email"); } this.email = email; } }

Pro-Tip: Follow Effective Java guidelines:

  • Item 15: Minimize the accessibility of classes and members
  • Item 16: In public classes, use accessor methods, not public fields

Summary: Private by default, public by necessity!

Topics Covered

Java FundamentalsModularity

Tags

#java#packages#access-modifiers#encapsulation#scope

Last Updated

2025-02-01