6.2 Java Source File Structure
The structure of a skeletal Java source file is depicted in Figure 6.1. A Java source file can have the following elements that, if present, must be specified in the following order:
- An optional package declaration to specify a package name. Packages are discussed in §6.3, p. 326.
- Zero or more import declarations. Since import declarations introduce type or static member names in the source code, they must be placed before any type declarations. Both type and static import declarations are discussed in §6.3, p. 329.
- Any number of top-level type declarations. Class, enum, and interface declarations are collectively known as type declarations. Since these declarations belong to the same package, they are said to be defined at the top level, which is the package level.
The type declarations can be defined in any order. Technically, a source file need not have any such declarations, but that is hardly useful.
The JDK imposes the restriction that at most one public class declaration per source file can be defined. If a public class is defined, the file name must match this public class. For example, if the public class name is NewApp, the file name must be NewApp.java.
Classes are discussed in §3.1, p. 99; interfaces are discussed in §5.6, p. 237; and enums are discussed in §5.13, p. 287.
Modules introduce another Java source file that contains a single module declaration (§19.3, p. 1168).
Note that except for the package and the import statements, all code is encapsulated in classes, interfaces, enums, and records. No such restriction applies to comments and whitespace.
Figure 6.1 Java Source File Structure
6.3 Packages
A package in Java is an encapsulation mechanism that can be used to group related classes, interfaces, enums, and records.
Figure 6.2 shows an example of a package hierarchy comprising a package called wizard that contains two other packages: pandorasbox and spells. The package pandorasbox has a class called Clown that implements an interface called Magic, also found in the same package. In addition, the package pandorasbox has a class called LovePotion and a subpackage called artifacts containing a class called Ailment. The package spells has two classes: Baldness and LovePotion. The class Baldness is a subclass of class Ailment found in the subpackage artifacts in the package pandorasbox.
The dot (.) notation is used to uniquely identify package members in the package hierarchy. The class wizard.pandorasbox.LovePotion, for example, is different from the class wizard.spells.LovePotion. The Ailment class can be easily identified by the name wizard.pandorasbox.artifacts.Ailment, which is known as the fully qualified name of the type. Note that the fully qualified name of the type in a named package comprises the fully qualified name of the package and the simple name of the type. The simple type name Ailment and the fully qualified package name wizard.pandorasbox.artifacts together define the fully qualified type name wizard.pandorasbox.artifacts.Ailment.
Java programming environments usually map the fully qualified name of packages to the underlying (hierarchical) file system. For example, on a Unix system, the class file LovePotion.class corresponding to the fully qualified name wizard.pandorasbox.LovePotion would be found under the directory wizard/pandorasbox.
Figure 6.2 Package Structure
Conventionally, the reverse DNS (Domain Name System) notation based on the Internet domain names is used to uniquely identify packages. If the package wizard was implemented by a company called Sorcerers Limited that owns the domain sorcerersltd.com, its fully qualified name would be
com.sorcerersltd.wizard
Because domain names are unique, packages with this naming scheme are globally identifiable. It is not advisable to use the top-level package names java and sun, as these are reserved for the Java designers.
Note that each component of a package name must be a legal Java identifier. The following package would be illegal:
org.covid-19.2022.vaccine
The package name below is legal:
org.covid_19._2022.vaccine
A subpackage would be located in a subdirectory of the directory corresponding to its parent package. Apart from this locational relationship, a subpackage is an independent package with no other relation to its parent package. The subpackage wizard.pandorasbox.artifacts could easily have been placed elsewhere, as long as it was uniquely identified. Subpackages in a package do not affect the accessibility of the other package members. For all intents and purposes, subpackages are more an organizational feature than a language feature. Accessibility of members defined in type declarations is discussed in §6.5, p. 345.