Public and Private Packages
I recently worked a project that provided one set of classes to the end user that are nice and simple and easy to understand, and used another set of classes to allow efficient computation. Consider the design for a graphics system shown in Figure 1.
Figure 1 The graphics data models, as a UML diagram.
The users of this software package need to manipulate the Object3D class. The implementation of render will need (internally) to first compile it into a set of triangles for easy manipulation. I don't want to expose the Triangle class to the user, but it needs to be public for the Object3D class to use it. The com.foocorp.server package is "public" in the sense that it's available to other classes in the overall com.foocorp hierarchy, but not generally available.
Java doesn't have any keywords to distinguish between "public" and "private" packages. The private keyword doesn't apply to packages. The solution is to provide Javadoc for those packages that are intended to be accessible to the user, and not for those that are for internal use only.
Indeed, one day somebody might even decide to reuse the com.foocorp.server classes to implement a totally different kind of 3D object representation. The client classes are coupled to the server classes, but not the other way around. That allows me to reuse the server without having to deliver the client. However, the client is completely useless without the server, so I must deliver it along with the client classes. But I don't want the particular implementation of Object3D to be exposed. For example, I may choose to replace it with an OpenGL package someday. But the server package must be public for the client classes to use it. So I deliver the compiled code, but refused to expose it by not running Javadoc on it.
In the UML diagrams, I can note this with a comment. That's not quite as nice as having a Java keyword for automatic processing, but it'll have to do. Fortunately, there tend to be a relatively small number of packages, even on a large project. It may be as many as a few dozen, but that's relatively easy to manage from the comments. That's compared to thousands of classes and millions of lines of code, where you must enlist the help of a compiler to enforce the restrictions.
Of course, the users could reverse-engineer the server classes, as many Java programmers have done with the com.sun packages provided in the Java Runtime Environment. But they'd be making assumptions I wouldn't promise to hold in the next release, even a small point-fix release.
Sometimes you have to contend with varying degrees of "public-ness," which conflict with each other. For example, the class javax.accessibility.AccessibleResourceBundle contains this notice:
This is meant only for internal use by Java Accessibility and is not meant to be used by assistive technologies or applications.
Most likely, this class was used at some point in development by multiple packages to share information. These packages were both themselves public and accessible to the user. They are cohesive internally, with only a single point of coupling: the class AccessibleResourceBundle. Since then, Java has refactored the code, and the class is now deprecated. Eventually it may go away entirely.