What is a Package?
A package in Java is a mechanism for organizing related classes and interfaces. Think of it as a folder or directory in a file system. It provides a namespace, which helps prevent naming conflicts. For example, you can have a class named `List` in your own package without it conflicting with Java's `java.util.List`.
Packages are essential for building large-scale, maintainable applications. They allow developers to group code logically, making it easier to find, use, and understand.
Key Benefits of Using Packages:
- Reusability: Classes in packages can be easily reused in other programs.
- Conflict Resolution: Two classes can have the same name as long as they are in different packages.
- Organization: Related classes and interfaces are bundled together, making the codebase easier to navigate.
- Access Control: Packages provide another layer of access control. Classes can be declared with no access modifier (package-private), making them accessible only to other classes within the same package.
Declaring a Package
To place a class or interface into a package, you use the package statement at the very beginning of your Java source file. It must be the first line of code, before any imports or class definitions.
The standard naming convention for packages is to use a reversed Internet domain name to ensure uniqueness, followed by project and module names.
// File: src/com/example/vehicles/Car.java
// This line declares that the Car class belongs to the 'com.example.vehicles' package.
package com.example.vehicles;
public class Car {
private String model;
public Car(String model) {
this.model = model;
}
public void drive() {
System.out.println(model + " is driving.");
}
}
Using Classes from Other Packages
If you want to use a class from another package, you have two options:
- Use the fully qualified name of the class every time you use it. This can be verbose.
- Use the
importstatement to bring the class into your current file's namespace. This is the more common and convenient approach.
// File: src/Main.java
// Option 1: Using the fully qualified name (verbose)
public class MainVerbose {
public static void main(String[] args) {
// Must use the full package path every time
com.example.vehicles.Car myCar = new com.example.vehicles.Car("Toyota");
myCar.drive();
}
}
// Option 2: Using the import statement (recommended)
import com.example.vehicles.Car; // Import the specific class
// import com.example.vehicles.*; // Or import all classes from the package
public class Main {
public static void main(String[] args) {
// Now we can use the class name directly
Car myCar = new Car("Honda");
myCar.drive();
// Classes from java.lang (like String, System) are imported automatically
String greeting = "Hello, World!";
System.out.println(greeting);
}
}
Mapping Packages to Folders
The package name directly corresponds to a directory structure on your file system. The Java compiler and JVM use this structure to locate your `.class` files. For a package named com.example.vehicles, the Car.class file must be located in a directory path like com/example/vehicles/.
A typical project structure might look like this:
MyJavaProject/
├── src/
│ ├── com/
│ │ └── example/
│ │ └── vehicles/
│ │ ├── Car.java
│ │ └── Truck.java
│ └── Main.java
└── out/ (or bin/) <-- This is where the compiled .class files go
├── com/
│ └── example/
│ └── vehicles/
│ ├── Car.class
│ └── Truck.class
└── Main.class
When you compile from the root of the `src` directory, the compiler will automatically create the corresponding directory structure in the output directory (`out` or `bin`). To run the `Main` class, you would navigate to the root of the output directory and execute:
# The command includes the full package name of the class to run
java Main
Telling Java Where to Look
The CLASSPATH is an environment variable or a command-line argument that tells the Java Virtual Machine (JVM) and the Java compiler where to look for user-defined classes and packages.
Think of it as a list of directories and JAR files that Java searches when it needs to load a class. If a class is not found in the default locations, Java will look in each path specified in the CLASSPATH.
Important Note: In modern software development, you rarely set the CLASSPATH environment variable manually. Integrated Development Environments (IDEs) like IntelliJ and Eclipse, and build tools like Maven and Gradle, manage the classpath for you automatically. However, understanding the concept is still fundamental.
You can set the classpath temporarily when running a program using the -cp or -classpath flag:
# Tells java to look for classes in the 'out' directory
# The '.' represents the current directory
java -cp out Main
# If you had external libraries (JAR files), you would include them too
# (on Windows, the separator is a semicolon ;)
java -cp "out:lib/my-library.jar" Main
Test Your Skills
- Create a package structure for your project:
com.yourname.utils. - Inside this package, create a class called
StringHelper. - Add a static method to
StringHelpercalledpublic static String reverse(String s). - Create another class called
Mainin the default package (no package statement). - In the
Mainclass, use theimportstatement to import yourStringHelperclass and use itsreversemethod.
🏆 Challenge: Application Structure
Design a package structure for a simple e-commerce application.
- Create a main package:
com.myapp. - Create sub-packages:
com.myapp.model,com.myapp.service, andcom.myapp.ui. - In the
modelpackage, create aProductclass with fields like `id`, `name`, and `price`. - In the
servicepackage, create aProductServiceclass with a methodpublic void displayProductDetails(Product p). This class will need toimporttheProductclass from themodelpackage. - In the
uipackage, create aMainAppclass with amainmethod. This class will create aProductinstance, create aProductServiceinstance, and call the service method to display the product's details.
// File: src/com/myapp/model/Product.java
package com.myapp.model;
public class Product {
private String id;
private String name;
private double price;
public Product(String id, String name, double price) {
this.id = id;
this.name = name;
this.price = price;
}
// Getters
public String getId() { return id; }
public String getName() { return name; }
public double getPrice() { return price; }
}
// File: src/com/myapp/service/ProductService.java
package com.myapp.service;
import com.myapp.model.Product; // Import the Product class
public class ProductService {
public void displayProductDetails(Product p) {
System.out.println("--- Product Details ---");
System.out.println("ID: " + p.getId());
System.out.println("Name: " + p.getName());
System.out.printf("Price: $%.2f%n", p.getPrice());
System.out.println("------------------------");
}
}
// File: src/com/myapp/ui/MainApp.java
package com.myapp.ui;
import com.myapp.model.Product;
import com.myapp.service.ProductService;
public class MainApp {
public static void main(String[] args) {
// Create a product
Product laptop = new Product("P101", "Super Laptop", 1299.99);
// Create a service
ProductService service = new ProductService();
// Use the service to display product details
service.displayProductDetails(laptop);
}
}