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);
}
}
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.