Oracle Blog

Blog for jglick

Wednesday Feb 17, 2010

Sometimes you need to expose a method from one class to another class, but do not wish to make this method public for anyone to call (because you are not prepared to maintain it compatibly forever). If they happen to be in the same package, you can just use package-private access. But this does not work if they are not in the same package.

Some module systems - NetBeans, OSGi - let you declare that some packages or classes are not to be accessed outside of the declaring module, even if marked public. The FriendPackages pattern can be useful in case you want to expose your method to a class in another package so long as that other package is private and is in the same module. But there are many cases where you want to make a method accessible to a particular caller in another module.

Ideally you could just use something like Java's public keyword - i.e., an annotation. But what would pay attention to that annotation? Well, an annotation processor. (At least at compile time; runtime access checks are another matter, but anyone using reflection probably knows how to call setAccessible anyway, so runtime checks would only be useful in security sandboxes.)

If you are compiling using JDK 7, the new AbstractTypeProcessor class in the Tree API lets you write annotation processors which not only can examine the full source tree, but get access to type information - such as what the receiver type of a method call is. This is critical.

I have started to prototype an annotation @Public which can be placed on a nominally public member to declare that it should be visible only to the enumerated classes; and an accompanying annotation processor: PublicProcessor By placing the JAR containing the annotation and its processor in your classpath, and compiling with JDK 7+ javac, you can have a new access modifier intermediate between package-private and public!