I have seen a number of posts on Stack Overflow and elsewhere assert that Java does not have the concept of subpackages. One thing often pointed out is the lack of any special access relationship between a package and its "subpackage". For instance, there is no way to expose a class or method in com.example
to classes in com.example.subpackage
(or vice versa) without exposing it to all other packages. However, despite these assertions, I see that the Java Language Specification does in fact define the concept of "subpackage" in Chapter 7. Packages and Modules.
The members of a package are class and interface types, which are declared in compilation units of the package, and subpackages, which may contain compilation units and subpackages of their own.
What, therefore, is a subpackage in Java, and what does it do?
Subpackages exist to allow code to be conveniently organized. They impose a restriction on class/interface naming (a class cannot have the same fully qualified name as a subpackage), but are otherwise no different than two unrelated packages.
The Java Language Specification defines what subpackages are in section 7.1, Package Members.
A subpackage is any package directly nested within another package. For instance, com.example.subpackage
is a subpackage of com.example
:
The members of a package are its subpackages and all the top level class types and top level interface types declared in all the compilation units of the package.
For example, in the Java SE Platform API:
- The package
java
has subpackagesawt
,applet
,io
,lang
,net
, andutil
, but no compilation units.- The package
java.awt
has a subpackage namedimage
, as well as a number of compilation units containing declarations of class and interface types.
Subpackages enforce naming constraints between subpackages and classes/interfaces within the package. Namely, a subpackage and a class/interface cannot share the same name within the same package:
A package may not contain two members of the same name, or a compile-time error results.
Here are some examples:
- Because the package
java.awt
has a subpackageimage
, it cannot (and does not) contain a declaration of a class or interface type namedimage
.- If there is a package named
mouse
and a member typeButton
in that package (which then might be referred to asmouse.Button
), then there cannot be any package with the fully qualified namemouse.Button
ormouse.Button.Click
.- If
com.nighthacks.java.jag
is the fully qualified name of a type, then there cannot be any package whose fully qualified name is eithercom.nighthacks.java.jag
orcom.nighthacks.java.jag.scrabble
.
The subpackage concept primarly exists for organizational purposes. The restriction against name conflicts is the only significance afforded to subpackages by the language:
The hierarchical naming structure for packages is intended to be convenient for organizing related packages in a conventional manner, but has no significance in itself other than the prohibition against a package having a subpackage with the same simple name as a top level type declared in that package.
For example, there is no special access relationship between a package named
oliver
and another package namedoliver.twist
, or between packages namedevelyn.wood
andevelyn.waugh
. That is, the code in a package namedoliver.twist
has no better access to the types declared within packageoliver
than code in any other package.