Concepts / Static Members of a Class

Static Members of a Class

A static nested class has full access to the static members of its containing class, including private ones, and the containing class has full access to the members of the nested class, including private ones.

  • Programming

A Problem Two Classes Share

Imagine two classes that belong together. One holds some data that the other needs to inspect or update while it does its work. The private access modifier normally stops outside code from touching that data, and that is usually a good thing. But when two classes are closely related, that same restriction can feel like it gets in the way. Java offers a structural answer to this problem: place one class inside the other. When the inner class is declared static, the pair gains a specific access relationship, and that relationship is the subject of this article.

Keep one question in mind as you read: if one class is nested inside another, which side is allowed to reach into the other's private members, and does that permission run in only one direction? By the end you should be able to answer that question with precision and to spot where the answer is often misunderstood.

Tracing a Shared Counter

Before we state any rule, we will trace a small program and watch the values change. The program below is an original teaching example. The outer class Bank keeps a private static counter called totalAccounts. Its private static nested class Ledger keeps its own private static counter called entries and has a static method record that updates both counters.

Code walkthrough
public class Bank {
    private static int totalAccounts = 0;

    private static class Ledger {
        private static int entries = 0;

        static void record() {
            entries++;
            totalAccounts++;
        }
    }

    public static void openAccount() {
        Ledger.record();
    }
}
  1. 1
    Line 2 declares the counter totalAccounts as private static. Only code inside Bank is supposed to see it under ordinary rules.
  2. 2
    Line 4 declares the nested class Ledger as private static. Because it is private, only code inside Bank can use it.
  3. 3
    Line 5 declares entries, a private static member of the nested class.
  4. 4
    Lines 7 to 10 define record. It increments entries in the nested class and also increments totalAccounts in the containing class, which the nested class is allowed to do.
  5. 5
    Lines 13 to 15 define openAccount in the containing class. It calls Ledger.record, which the containing class is allowed to do because it contains the nested class.
  • totalAccounts is private to Bank, but Ledger is nested inside Bank and can reach it
  • Ledger is declared private, so only code inside Bank can name it
  • entries is private to Ledger, and Bank may reach it as well because Bank contains Ledger
  • openAccount is in the containing class and calls into the nested class
Before
totalAccounts = 0
entries = 0

Both static counters start at zero before any call is made.

After
totalAccounts = 1
entries = 1

openAccount calls record once. Ledger.record increments entries to 1, and it also increments totalAccounts to 1.

Worked example

Following one call through both classes

Starting from both counters at zero, what are the values of totalAccounts and entries after Bank.openAccount runs two times?

  1. 1
    First call

    openAccount calls Ledger.record. Inside record, entries becomes 1 and totalAccounts becomes 1.

  2. 2
    Second call

    openAccount runs again and calls record again. entries becomes 2 and totalAccounts becomes 2.

  3. 3
    Check the access

    Every step that touched a private member was performed by code in one of the two classes. The nested class touched the containing class's private counter, and the containing class called into the nested class's private structure. No getter or setter was needed.

Result

After two calls, totalAccounts is 2 and entries is 2.

Two-Way Access Between the Classes

The central rule is that the two classes trust each other. A static nested class has full access to the static members of its containing class, and this access reaches even the members marked private. Turning the relationship around, the containing class has full access to the members of the nested class, including any that are marked private. Neither side needs a getter, a setter, or any other public door to reach across. The privacy boundary is not a barrier between these two classes.

The access is deliberate and specific. It comes from the structure of the nesting itself. Code elsewhere in the program does not inherit this permission just because it sits in the same package or the same project. The source is explicit that being in the same package does not grant access to a private nested class.

Bank (containingclass)private statictotalAccountsLedger (static nestedclass)private static entriesreaches private totalAccountsreaches private entries and record
How do the containing class and its static nested class each reach the other's private members, and in which direction does each access flow?

Read the diagram as a pair of arrows. The nested class reaches upward into the private members of its container. The container reaches downward into the private members of the nested class. Both arrows exist at the same time, and that is what makes the arrangement two-way rather than one-way.

Where the Code Must Be Written

The access rule above concerns the members inside the two classes. A second rule concerns the nested class itself. A nested class can be declared private, and such a class can only be used inside the class in which it is nested. Its existence is visible to its container, and nothing outside that container can name it or create objects from it. Whether a piece of code may use the private nested class therefore depends on where that code is written, not on which package or file it lives in.

Bankcontaining classLedgerprivate nested classCode inside Ledgercan reach Bank privatemembersCode inside Bankcan use LedgerAuditorcannot name or use Ledgercontainscontainscontains
If a piece of code sits inside the containing class, inside the nested class, or entirely outside both, which private members and nested classes can it reach?

The tree-like picture is useful because the usability of a private nested class follows its place in the structure. Code inside the containing class is inside the zone where the private nested class is usable. Code located elsewhere, with no nesting relationship to the container, falls outside that zone and cannot use the nested class at all.

What do you think happens?

Suppose a separate top-level class called Auditor, in the same package as Bank, tries to call Bank.Ledger.record(). Will it compile?

Reveal answer
Answer:

No. Auditor cannot use the private nested class Ledger.

Ledger is private, so it is usable only inside Bank. Being in the same package does not grant access to a private nested class, so Auditor has no path to name or call it.

java
Notes on the code
  • Auditor is outside the containing class Bank
  • Ledger is private, so this reference is not allowed from here

Why Choose Nesting

The main benefit of a nested class is selective sharing. You can let one class see the private internals of another without making those internals generally available to every other class in the program. Ordinary private members stay hidden from the rest of the world, while the one partner class that genuinely needs them is given a path in.

Design choiceWho can reach the shared internalsWhat the design says about the relationship
Private static nested classOnly the containing class and the nested classThe two classes are closely related and share narrow internal details
Public top-level class with public membersAny code that can see the classThe internals are open to the whole program, which widens the surface other code can depend on
Top-level class with private members and no nestingOnly code inside that same class, so a partner needs public getters or settersThe partner must go through public doors, which is less selective than a nested arrangement

How nesting limits visibility compared with wider alternatives

Common Misunderstandings About Privacy

The two-way trust between a containing class and its static nested class is easy to misremember. The following misunderstandings come up often, and each one is contrasted with the correct rule.

  • Common mistake

    Assuming that a private nested class is visible to the whole package

    What it looks like

    Auditor, in the same package as Bank, tries to use Bank.Ledger

    Why it fails

    Being in the same package does not grant access to a private nested class. Only code inside the containing class can use it.

    Do this instead

    Decide usability by where the code is written. Code outside the containing class cannot use the private nested class.

  • Common mistake

    Believing that the containing class needs a getter to read the nested class's private members

    What it looks like

    Bank tries to read Ledger.entries through a public getter that was never written

    Why it fails

    The containing class has full access to the members of the nested class, including those marked private. No public door is required.

    Do this instead

    Read the private member directly from the containing class when the code is inside it.

  • Common mistake

    Thinking the access runs in only one direction

    What it looks like

    Concluding that Ledger can read Bank's private counter, so Bank cannot read Ledger's private counter

    Why it fails

    The source describes the relationship as two-way. Both classes reach each other's private members.

    Do this instead

    Check both arrows. The nested class reaches up into the container, and the container reaches down into the nested class.

  • Common mistake

    Assuming that nesting is always the right way to share data

    Why it fails

    The source frames nesting as appropriate for a genuinely close relationship with narrow sharing. Using it for loosely related classes can hide a design problem.

    Do this instead

    Before nesting, ask whether the two classes truly belong together and whether only one partner needs the data.

Practice Reasoning About Access

MEDIUM

Using the Bank and Ledger program from earlier, decide whether each of the following is allowed. (a) A method inside Bank reads Ledger.entries directly. (b) A method inside Ledger increments Bank.totalAccounts. (c) A class Teller in a different file of the same package calls Bank.Ledger.record(). For each, name the rule from this article that justifies your answer.

Hints
  • Ask which class the code sits inside, since that determines what it can reach.
  • The containing class and the static nested class each have full access to the other's private members.
  • Being in the same package is not enough to use a private nested class.

Key Takeaways

  • A static nested class has full access to the static members of its containing class, including private ones, and the containing class has full access to the members of the nested class, including private ones.
  • The two-way access exists because of the nesting structure itself. It lets two closely related classes share private internals without exposing them to the rest of the program.
  • A nested class declared private can only be used inside the class in which it is nested. Being in the same package does not grant access.
  • Choose nesting when the relationship between the two classes is genuinely close and the sharing is genuinely narrow, not as a general way to avoid designing visibility.