Accessibility is the other side of the Java modularity coin. If the readability relationship specifies what modules can read a given module, accessibility indicates what they actually do get when they read it. Not everything in a module is accessible to the other modules that read it. Only the public types in packages that are marked with an exports declaration are.
Thus, for a type in module B to be accessible in module A, the following needs to happen:
- Module A needs to read module B
- Module B needs to export the package that contains the type
- The type itself should be public
Let's look at an example and examine the readability and accessibility relationships. Consider two modules, app and lib. Module app has a requires qualifier for module lib. Module lib exports its package lib.external:
module app { requires lib; } module lib { exports lib.external; }
Let's say the lib module has the following structure:
It has two packages--lib.external and lib.internal. Both packages contain one public interface and one package-private implementation.
Let's try to answer the following questions:
- Does module app read module lib?
This one should be simple. The answer is yes, because of the requires qualifier.
- Does module lib read module app?
The answer is no. Hopefully equally simple!
- Is the type LibApi in module lib accessible to module app?
Let's verify the two requirements for accessibility. Is the type public? Yes. Is the type in a package that's exported by the module? Yes. So, the answer is LibApi is accessible to module app.
- Is the type InternalService in module lib accessible to module app?
No. Because even though the type is public, it belongs to a package that is not exported in the module definition of the lib module. The type InternalImpl is also not accessible to the app module.
- Is the type LibApiImpl in module lib accessible to module app?
The answer is no, because it fails the requirement--is the type public? Since LibApiImpl is package-private, it is not accessible outside the module, since it's not public. This is true even though the type belongs to an exported package. This scenario is, however, more interesting with a couple of important lessons we can learn from it. Let's look at them in detail.