Both Scala and Java differ from the JVM’s model of access control. A private member of a JVM class is only accessible to that class, but at the language level, a private member is accessible to enclosing or inner classes. In Scala, companion classes/objects also have mutual private access.
Scala additionally supports qualified private access that can extend across compilation units. Its package semantics differ from Java: a.b.c can see private[b] members, so this cannot be mapped to JVM package-private without introducing accessor methods.
Historically, Java emitted synthetic accessor methods or constructors to bridge this language vs VM mismatch. Scala took a different approach: because it also needs to handle cross-compilation-unit access, it emits such members as JVM public with mangled names.
Java 11 introduced nestmate-based access control (JEP 181). The relationship between inner and enclosing classes is made explicit via new classfile attributes, and the JVM uses this to treat a nest as the unit of private access.
With a baseline of JDK 11+, it seems worthwhile to take advantage of nestmate access control. This is designed for inner ↔ outer private access in Java, which previously relied on synthetic bridge methods.
Scala could use this to avoid manging/widening for non-qualified private members referenced by inner/enclosing classes, and by companion objects/classes.
It would not help with to qualified privates that extend beyond the compilation unit boundary.
Benefits:
- Cleaner bytecode and stack traces (fewer mangled names)
- Fewer false positives in binary compatibility checks (e.g. MiMa: "Private" primary constructor vs MiMa - #4 by smarter)
A prototype suggests the implementation is relatively straightforward: Implement JEP 181 Nestmate attributes and support in ExpandPrivate by retronym · Pull Request #1 · retronym/dotty-1 · GitHub