I was shocked today to discover that this code compiles cleanly in Java:
public class A {
public static class B {
private static void x() {}
}
private static class C {
private /* So, private to what exactly? */ static void x() {}
}
public static void main(String[] args) {
B.x(); C.x();
}
}
It seems Java's private keyword indicates only top-level-class-privacy; which, given the general convention to name Java source files by class, means that Java effectively provides only file-level private visibility, not true private visibility. (The equivalent code in C++ does not compile with a visibility error.)
Would anyone be able to explain why Java was designed this way? Or is this just Java's way of telling everyone not to use nested classes? (It certainly hacks in an implementation of a two-way C++ friend relationship, but we already have package-level visibility for that; this seems to make the one-way equivalent impossible. Moreover, it necessitates the compiler creating more hidden accessor methods to circumvent the visibility, and under-the-hood downgrading of nested class visibility control to make all this not error out at runtime. Really, why the trouble?)
javac
, Martin Odersky, seems to feel the same way: when inventing Scala, he made the effect configurable, so that the programmer can decide whether something is private to its class, to its class and superclass, or to the file, etc.