Java: Package
In Java, code can be organized into files, each file is a public class, and classes can be organized into packages, that's a directory of class files. A directory of class files is called “package”. This page show how it works.
How Java Package Works, Summary
Code can be organized into class files.
- One public class per file.
- The class name and file name must be the same. (e.g. if a file is named “Abc.java”, then it must contain a public class named “Abc”.)
A set of class files can be placed into a directory, to form a package.
- To create a “package”, put class files in a directory, and each file must declare
package dirName;
- package directory can be nested. That is, class files are placed in nested directories, and each class file must declare its dir paths, separated by dot, like this
package dir1.dir2;
.
Here's how to reference/import a class in a file or package.
- The main program can refer to classes in a directory by full name, like this:
dirName.className
. The dirName is relative to themain
's file dir. - The
import
keyword is used to avoid typing long reference names to classes. e.g.import food.Cheese;
, then you cannew Cheese
. To import all classes in a dir, use asterisk. Example:import food.*;
- Java import classes, not packages. The syntax
import food.*
imports all classes under food dir, but does not import classes in subdirectories of food dir, andimport food.*.*
is invalid syntax.
The rest of this page are details.
One Public Class Per File
In Java, you can put each class definition in a file.
// Save this in a file named Cheese.java class Cheese { Cheese () { System.out.println("say Cheese."); } }
// Save this in a file named RunMe.java, in the same dir as Cheese.java class RunMe { public static void main(String[] args) { Cheese c = new Cheese(); System.out.println("Cheese called!"); } }
Now, compile it javac RunMe.java
and run it java
RunMe
. As you can see, RunMe is a program that calls the class
Cheese in another file. In this way, you can have different files
holding different classes, and calling these classes from a main
file.
- In Java, each file should contain only one class definition that will be visible outside the file.
- The class's name must be the same as the file name. (if you have a file
Cheese.java
, then in that file you must have a public class named Cheese. Else it won't compile)
If there are more than one class definition in a file, only the one with the file name is available for other program to use. Other classes in the file can not be called by code outside of the file.
For example try change the Cheese.java
to the following:
class Cheese { Cheese () {System.out.println("say Cheese.");} Chicken c = new Chicken(); } class Chicken { Chicken () {System.out.println("say Chicken.");} }
Now compile and run “RunMe” again. It all still work. Now both Cheese and Chicken are considered your subroutine tucked away neatly in a file. “Cheese” is the main one, identified by the file's name, while “Chicken” is a helper, not to be used outside of Cheese.java
.
Now, try to put public
in front of Chicken and see what happens. You'll see that it's a compiler error, because java does not allow a file to have more than 1 class to be visible outside the file. (and the one class visible outside must be the one having same name as the file.)
Try also private
or protected
in front of Cheese.
〔see Java: Access Specifiers〕
Package = Set of Classes in a Directory
You can organize class files into directories. For example, you can have a directory named “sound” that contain all classes that deals with sound, and another directory named “images” that contains all classes that deals with pictures, of your video game program.
// save me as StartMe.java class StartMe { public static void main(String[] args) { pacman.Ladybug lb = new pacman.Ladybug(); System.out.println("StartMe done"); } }
Now, create a directory there named “pacman”. Then, save the following code there as Ladybug.java
.
// save me as Ladybug.java in a directory pacman package pacman; public class Ladybug { public Ladybug () { System.out.println("Ladybug initialize!"); } }
Now, compile StartMe.java
and run it. As you can see, the class StartMe calls the Ladybug class under the pacman dir by this full reference: pacman.Ladybug
. This is how Java calls classes in another directory.
Also, note that the Ladybug.java
file starts with the line package pacman;
. If you put a file into a directory as part of a package, that file needs to start with the line package dirName;
(otherwise, that file won't be part of your package).
Also, note that the two public
keywords in Ladybug needs to be there. Otherwise it won't compile. (try to experiment by changing the access specifier and compile.)
〔see Java: Access Specifiers〕
Package Nested Subdirectories
A package can have more than 1 level of subdirectories.
Suppose you have a collection of codes related to sound in a video game program. You put them under a “sound” directory. Now, some of these are related to processing sounds, while others are playing sounds. So, you can create subdirectories “process” and “play” as nested packages, to further organize your code.
Using our previous example, in the “pacman” dir create a directory “maze”, and in the “maze” dir create a file Labyrinth.java
with the following code:
// save me as Labyrinth.java in directory pacman/maze package pacman.maze; // this is dir structure! public class Labyrinth { public Labyrinth () { System.out.println("i trap Minotaur!"); } }
And add a line to StartMe.java
to call “Labyrinth”:
class StartMe { public static void main(String[] args) { pacman.Ladybug lb = new pacman.Ladybug(); pacman.maze.Labyrinth rring = new pacman.maze.Labyrinth(); System.out.println("StartMe done"); } }
So now we have these files and directory structure:
StartMe.java pacman/ ◆Ladybug.java ◆maze/ ◆◆Labyrinth.java
Now compile and run StartMe.
Use 「import」 to Import a Class
To refer to a class in a package, you can:
- Use the full name, like this:
new pacman.maze.Labyrinth()
. - Use
import a.b.C
to import the class C, then you can refer to a class named C directly, as innew C
.
import pacman.maze.Labyrinth; // import the class Labyrinth, under dir pacman/maze class StartMe { public static void main(String[] args) { pacman.Ladybug lb = new pacman.Ladybug(); Labyrinth rring = new Labyrinth(); // short, because we imported Labyrinth System.out.println("StartMe done"); } }
Import Many Classes: *
If you have many classes under a dir, you import them all with asterisk as wildcard, like this:
import pacman.*
Java import classes, not packages.
For example, import pacman.*
does not import classes in “pacman.maze”, and import pacman.*.*
is invalid syntax.
Interfaces in a Package
Java interfaces can also be put into a package, just like classes. Like classes, it should be one interface per file.
〔see Java: Interface〕
Default Package
If the file didn't declare a package, it is then in a “default package”, which is a package without name.
Pack Packages into Jar Archive
A package (a directory of classes) can be packages into a jar archive, one single file. Jar file is the standard way to distribute Java libraries and applications.