Search code examples
javaclassprivate

What is the purpose of a private nested/inner class?


I was under impression that a private inner/nested class is only used for/by/accessed by outer class. But experimenting I realized that the HashSet(which is not the outer class of Happy) can access the class. If so then what is the real use of private ? Is it only restricting creation of classes to within outer class ?

public class FreeMain {

    private static class Happy {
       int x; 
       private Happy(int x) {
           this.x = x;
       }

       @Override
       public boolean equals(Object o) {
           return true;
       }

       @Override
       public int hashCode() {
           return 10;
       }
    }

    public static void main(String[] args) {
        Set<Happy> happiness = new HashSet<Happy>();

        Happy h1 = new Happy(10);
        Happy h2 = new Happy(20);

        happiness.add(h1);
        happiness.add(h2);
    }   
}

Solution

  • Access modifiers in Java control the scope in which an identifier can be legally accessed or referenced. You are using your private nested (static => nested, non-static => inner) class as the type parameter to a HashSet—but the reference is still happening within the scope of the parent class.

    If so then what is the real use of Private ? Is it only restricting creation of classes to within outer class ?

    No, it doesn't just restrict creation. You can't even reference the type Happy outside the FreeMain class. If you try to declare something with type Happy, or use Happy as a type parameter (like Set<Happy>) outside class FreeMain, you'll get a compiler error.


    To summarize, if reference to private nested class is passed to another class(like set), it works so long as its in scope of freemain.

    Yes, that's basically correct. However, the type isn't really being "passed" to Set when you declare a Set<Happy>. None of the code in the Set class ever sees the actual type you provide in the parameter (due to type erasure). The Java compiler just uses the information you specify in the type parameters as a kind of type assertion to check the correctness of your program.

    When you declare Set<Happy> happiness, the fact that the happiness contains Happy instances is not known anywhere but within the scope of happiness. Therefore, the Happy type is never actually used outside the scope of your FreeMain class, and that's why it's legal even though Happy is private.