Package in Java
Classes and interfaces are arranged in Java using packages, which also help to regulate access, avoid naming conflicts, and simplify code management. They serve as containers for classes and other smaller packages, in essence.
A Java file package
statement, which appears as the first statement, is used to define a package. According to this statement, the classes declared in that file are part of the namespace. If you leave out the package
statement, the classes are put in the nameless default package. For real-world applications, establishing explicit packages is essential to prevent name clashes and enhance organisation, even though it is appropriate for tiny example programs.
A package statement follows this general form: package pkg;
For example, package mypack;
declares that classes in the file belong to mypack
. Java supports hierarchical packages, where package names are separated by periods. The general form for a multi-level package statement is package pack1.pack2.pack3...packN;
. For example, package alpha.beta.gamma;
implies a package hierarchy.
Creating Packages (Directory Structure)
Java uses the file system to manage packages, meaning that the directory structure must mirror the package hierarchy. If you declare a class to be part of MyPackage
, its .class
files must be stored in a directory named MyPackage
. Similarly, for a hierarchical package like java.awt.image
, the classes would be stored in java/awt/image
(on Unix-like systems) or java\awt\image
(on Windows). It is essential that package names are case-sensitive and match their corresponding directory names exactly. To avoid problems, it’s best to keep all .java
and .class
files for a package within that package’s directory.
Accessing Packages
The Java runtime system must be aware of package locations. Usually, this is ascertained in three ways:
- Current Working Directory: Java by default looks through the current working directory’s subdirectories.
- CLASSPATH Environment Variable: It is possible to configure the
CLASSPATH
environment variable to include directory paths containing packages. Not the package directory itself, but the root directory holding the package hierarchy should be the location of theCLASSPATH
. Colonies (Unix) or semicolons (Windows) are used to separate several routes inCLASSPATH
. - -classpath Option: You can use the
-classpath
option withjava
andjavac
commands to specify the path to your classes at runtime or compilation.
Import Statements
Java offers the import
statement as an alternative to repetitive fully qualified names (such as bookpack.Book
). By bringing one or more package members into view using an import
statement, you can use them by their straightforward names without the need for package qualification.
import
statements appear immediately after the package statement (if present) and before any class definitions in a Java file.
There are two general forms of the import
statement:
- Importing a Single Class:
import pkg.classname;
- Example:
import java.util.Date;
makes theDate
class directly accessible.
- Example:
- Importing an Entire Package:
import pkg.*;
- The asterisk (
*
) imports all public classes within that package. - Example:
import java.io.*;
imports all classes in thejava.io
package.
- The asterisk (
Because it contains essential classes, the special package java.lang
is automatically imported into all Java programs. Therefore, you don’t need to explicitly import java.lang.System
to use System.out.println()
.
It is crucial to remember that if two packages are imported using the * wildcard and classes with the same name are present in both of them, the compiler will generate a compile-time error if you attempt to use one of them. In such cases, you will need to explicitly name the class with the complete package specification.
Access Control and Packages
Additionally, packages are a part of Java’s access control system. Apart from the public
, private
, and protected
modifiers, Java also specifies an implicit access level.
- Users with default access can see each other inside their own package, but not outside of it. Without disclosing information to the outside world, this enables classes in the same package to have “intimate knowledge” of one another.
- A class with default access can only be accessed by other code that is part of the same package, but a public class can be accessed by any other code.
- A file bearing the same name as the class is required to contain a public class.
Naming Conventions for Packages
Java has created particular package name guidelines for clarity and to avoid any conflicts:
- All Lowercase: It is recommended that package names be written exclusively in lowercase letters.
- Reversed Internet Domain Name: Package names usually start with the inverted Internet domain name of the company or organisation that created the package for uniqueness. An organisation that owns the domain
apple.com
, for instance, would begin the names of its packages withcom.apple
. - Single Nouns: Avoid using plural forms for single nouns.
Java.lang.annotation
is a better option thanJava.lang.annotations
, for example. - No Special Characters: There should be no underscores or other special characters in package names.
Code Example: Book Package
A straightforward example with two packages can help us better understand these ideas.
Define the Book
class in the bookpack
package. Create a directory named bookpack
. Inside bookpack
, create Book.java
.
// File: bookpack/Book.java
package bookpack;
public class Book {
private String title;
private String author;
private int pubDate;
// Public constructor for use outside the package
public Book(String t, String a, int d) {
this.title = t;
this.author = a;
this.pubDate = d;
}
// Public method to display book details
public void show() {
System.out.println(title);
System.out.println(author);
System.out.println(pubDate);
System.out.println();
}
}
Explanation: The Book
class is declared public
so it can be accessed from outside the bookpack
package. Its constructor and show()
method are also public
for the same reason.
Define the UseBook
class in the bookpackext
package. Create a directory named bookpackext
at the same level as bookpack
. Inside bookpackext
, create UseBook.java
.
// File: bookpackext/UseBook.java
package bookpackext;
import bookpack.Book; // Import the specific Book class from bookpack
public class UseBook {
public static void main(String args[]) {
Book books[] = new Book[89]; // Now Book can be used directly
books = new Book("Java: A Beginner's Guide", "Schildt", 2014);
books = new Book("The Complete Reference", "Schildt", 2014);
books = new Book("Effective Java", "Bloch", 2008);
for(int i=0; i < books.length; i++) {
books[i].show();
}
}
}
Explanation: The UseBook
class is in a different package (bookpackext
). It uses an import bookpack.Book;
statement to make the Book
class accessible by its simple name. Without this import, Book
would need to be fully qualified as bookpack.Book
every time it’s used.
Compile and Run the Programs From the directory containing both bookpack
and bookpackext
folders:
- Compile Book.java:
javac bookpack/Book.java
- Compile UseBook.java:
javac bookpackext/UseBook.java
- Run UseBook:
java bookpackext.UseBook
Code Output:
Java: A Beginner's Guide
Schildt
2014
The Complete Reference
Schildt
2014
Effective Java
Bloch
2008
This result shows that UseBook used the package and import commands to correctly obtain and use the Book class from a separate package.