Back to Inner Classes
Q2Question 2 of 2

Can you make a class private?

Key Concepts
  • A top-level class CANNOT be private or protected – only public or package-private (default)
  • A nested/inner class CAN be private – visible only to its enclosing class
  • Private nested classes are used for implementation details: cache, node, builder internals
  • Understanding this concept is essential for Java interviews at senior level
  • This concept directly affects how banking applications manage resources

Definition

A top-level class cannot be private (compiler error). A nested class can be private, visible only to its enclosing class.

Access rules for classes:

  • Top-level: Only public or default (package-private). private class X {} at top level does not compile.
  • Nested/inner: All four modifiers work: public, protected, default, private.
  • Private nested: Used for internal implementation classes like cache entries, linked list nodes, builder internals.

A bank branch (top-level class) is either open to the public or known within the district (package-private). But a room inside the branch (nested class) can be private – like the vault, accessible only to the branch itself.

Understanding the Concepts

Why can a top-level class not be private?

JAVA
// COMPILE ERROR: modifier 'private' not allowed here
// private class Secret { }

// OK: package-private (visible within the package)
class Internal { }  // no modifier = package-private

// OK: public (visible everywhere)
public class Account { }

A top-level class has no enclosing class to be private relative to. Private means "visible only to the enclosing class," which does not apply at the top level.

Private nested class

JAVA
public class AccountCache {
    // Private: only AccountCache can use CacheEntry
    private static class CacheEntry {
        final String accountId;
        final Account account;
        final long timestamp;

        CacheEntry(String id, Account acc) {
            this.accountId = id;
            this.account = acc;
            this.timestamp = System.currentTimeMillis();
        }
    }

    private final Map<String, CacheEntry> entries = new HashMap<>();

    public void put(String id, Account account) {
        entries.put(id, new CacheEntry(id, account));
    }
}

// AccountCache.CacheEntry is invisible outside AccountCache

This is good encapsulation: the internal data structure is hidden from external code.

What should a senior engineer know?

  • HashMap.Node is package-private nested, not private, because LinkedHashMap (in the same package) extends it.
  • In a file, only one top-level class can be public, and it must match the filename. Additional top-level classes in the same file must be package-private.

What are common mistakes?

A common mistake is not understanding the concept fully before using it in production banking applications.

Wrong approach:

JAVA
package com.bank.service;

public class TransferService {
    public void transfer(String fromAccount, String toAccount, double amount) {
        // WRONG: using double for money
        double balance = getBalance(fromAccount);
        balance = balance - amount;
    }
    private double getBalance(String id) { return 10000.0; }
}

Correct approach:

JAVA
package com.bank.service;

import java.math.BigDecimal;

public class TransferService {
    public void transfer(String fromAccount, String toAccount, BigDecimal amount) {
        // CORRECT: using BigDecimal for money
        BigDecimal balance = getBalance(fromAccount);
        balance = balance.subtract(amount);
    }
    private BigDecimal getBalance(String id) { return new BigDecimal("10000.00"); }
}

Always use BigDecimal for monetary calculations in banking systems to avoid floating-point precision errors.

What are the edge cases?

Edge cases can cause unexpected behavior in banking applications. Here are some to watch for.

JAVA
package com.bank.edge;

public class EdgeCaseDemo {
    public static void main(String[] args) {
        // Edge case 1: null handling
        String accountId = null;
        try {
            System.out.println(accountId.length());
        } catch (NullPointerException e) {
            System.out.println("Null account ID");
        }

        // Edge case 2: empty vs null
        String emptyId = "";
        System.out.println(emptyId.isEmpty());  // true
        System.out.println(emptyId == null);     // false

        // Edge case 3: boundary values
        java.math.BigDecimal zero = java.math.BigDecimal.ZERO;
        java.math.BigDecimal negativeBalance = new java.math.BigDecimal("-0.01");
        System.out.println(zero.compareTo(negativeBalance) > 0);  // true
    }
}
TEXT
Null account ID
true
false
true

Always test with null values, empty strings, boundary values, and negative amounts in banking applications.

What are common interview follow-up questions?

Interviewers often follow up with these related questions:

  • How does this concept apply to a high-throughput banking transaction system?
  • What are the performance implications in a production environment?
  • How would you debug issues related to this concept?
  • What tools would you use to monitor this in production?
  • How does this behave differently in Java 8 vs Java 17+?

When answering follow-up questions, always relate your answer back to practical experience. For example, at National Bank of India, Rajesh debugged a production issue related to this concept by using JFR recordings and heap dumps. Providing concrete examples from banking systems shows the interviewer that you understand both the theory and the practice.

Visual Overview

DIAGRAM
  Top-level class:   public or default (no modifier)
                     private → COMPILE ERROR
                     protected → COMPILE ERROR

  Nested/inner class: all four modifiers allowed
                     private = visible only to enclosing class
                     Used for: cache entries, nodes, builder internals

Key Takeaway

A top-level class cannot be private because there is no enclosing class for it to be private relative to. Only public and package-private are allowed. A nested class can use all four access modifiers, and private nested classes are commonly used for internal implementation details.

One sentence to remember: top-level classes are public or package-private – only nested classes can be private.

---

Share
Use ← → arrow keys to navigate