Today, I enabled Eclipse to warn me when my code accesses a “non-accessible member of an enclosing type” and learned something in the process.
From what I gather, code like the following:
causes the compiler to generate a package-private “synthetic” accessor method inside OuterClass to allow InnerClass to see the private LOG instance. From what I read, it seems since the inner class is compiled to a separate .class file, the runtime needs some way for inner class instances to access the private members of the outer class. Syntactically, and according to the Java Language Specification, non-static inner classes are allowed to access private variables and methods in outer classes. But how do those inner-class instances access the private fields and methods?
The solution most Java compilers seem to implement is to add extra (the JLS calls them “synthetic”) package-private accessors to the outer class to allow the inner classes to see the private information.
My inner class in question is a private custom Iterator that I don’t want others accessing directly. When I compiled the class in Eclipse with the “Access to a non-accessible member of an enclosing type” set to “Warning” (Window > Preferences > Java > Compiler > Advanced), it warned me that “Read access to enclosing field OuterClass.LOG is emulated by a synthetic accessor method. Increasing its visibility will improve your performance.” So I searched around to find out what all this meant, starting my journey.
My search led first to this blog entry from Vladimir Roubtsov. That led me to an archived discussion of the topic from the ADVANCED-JAVA@DISCUSS.DEVELOP.COM mailing list to help shed more light on the subject. Vladimar’s blog also references a discussion on this topic on the Eclipse cdt-dev mailing list, but it requires you to sign up to read that archived discussion. That discussion might delve further into what performance penalty you might pay by accessing the private members via generated accessors.
Since I don’t want to increase the visibility of the private fields in my outer class, I’m going to live with any performance hit rather than break encapsulation.