Chapter 40 of 57

Packages in Java

As your Java programs become larger, you'll eventually have many classes. Keeping hundreds of classes in one place can become difficult to manage.

Java provides packages to help us organize related classes and avoid naming conflicts.

You can think of a package like a folder on your computer. Just as you might put related files inside the same folder, Java lets us put related classes inside the same package.

For example:

com.myapp
├── Student.java
├── Teacher.java
└── Course.java

Here, Student, Teacher, and Course can all belong to the same package.

Creating a Package

We use the package keyword to specify which package a class belongs to.

For example:

package school;

class Student {
    String name;
}

Here, school is the package name.

The package statement normally appears at the top of the Java file, before the class declaration.

package school;

public class Student {
    String name;
}

Now the Student class belongs to the school package.

Why Do We Use Packages?

Packages are mainly useful for organizing code.

Imagine you're building a large application with classes related to users, payments, products, and orders.

Instead of keeping everything together, you could organize them like this:

com.myapp
│
├── users
│   ├── User.java
│   └── UserService.java
│
├── payments
│   ├── Payment.java
│   └── PaymentService.java
│
└── products
    ├── Product.java
    └── ProductService.java

Now it's much easier to find and manage related classes.

Packages can also help prevent name conflicts.

For example, two different packages could contain a class called User:

com.company.admin.User
com.company.customer.User

Both classes can exist because they belong to different packages.

Importing a Class from Another Package

Suppose we have a Student class inside the school package:

package school;

public class Student {
    public void showName() {
        System.out.println("John");
    }
}

Now suppose we want to use Student from another package.

We can use the import keyword:

import school.Student;

Then we can create a Student object normally:

import school.Student;

class Main {
    public static void main(String[] args) {

        Student student = new Student();

        student.showName();
    }
}

Output:

John

The import statement tells Java where to find the Student class.

Importing Multiple Classes

Suppose a package contains several classes:

school
├── Student
├── Teacher
└── Course

We can import the classes we need individually:

import school.Student;
import school.Teacher;
import school.Course;

Or we can import all accessible classes from the package using *:

import school.*;

The * means all accessible classes in that package.

It's worth remembering that this does not include classes from subpackages automatically.

For example:

school
school.students

Importing:

import school.*;

does not automatically import classes from school.students.

Fully Qualified Class Name

We don't always have to use import.

We can directly use the fully qualified name of a class.

For example:

school.Student student = new school.Student();

Here:

school.Student

is the fully qualified class name.

This can be useful when two packages contain classes with the same name.

Java's Built-in Packages

Java comes with many packages that contain useful classes.

One of the most commonly used packages is:

java.lang

It contains classes such as String, Math, System, and Integer.

For example, we can use:

String name = "John";

without writing:

import java.lang.String;

That's because java.lang is automatically imported by Java.

Another commonly used package is:

java.util

It contains useful classes such as ArrayList, Scanner, and HashMap.

For example:

import java.util.Scanner;

Now we can use Scanner in our program.

Packages and Folder Structure

In a normal Java project, the package structure usually matches the folder structure.

For example:

src
└── school
    └── Student.java

And the file might contain:

package school;

public class Student {
    
}

The Student.java file is inside the school folder, matching the package name.

Modern Java build tools such as Maven and Gradle also use package structures extensively when organizing larger applications.

Package Naming Convention

Java packages are usually written in lowercase.

For example:

com.company.project
org.example.app
com.myapp.users

A common convention is to start with a reversed domain name.

For example, if a company's domain is:

example.com

its packages might start with:

com.example

Then it could have:

com.example.users
com.example.products
com.example.payments

You don't need to worry too much about this for small beginner programs, but you'll see this convention frequently in real Java projects.

A Simple Example

Let's create a small package named school.

Student.java

package school;

public class Student {

    public void introduce() {
        System.out.println("Hello, my name is John.");
    }
}

Then in another class:

import school.Student;

class Main {
    public static void main(String[] args) {

        Student student = new Student();

        student.introduce();
    }
}

Output:

Hello, my name is John.

Here, the Student class belongs to the school package, and Main imports it so that it can use the class.

The main idea is simple:

Packages help us organize Java classes, avoid naming conflicts, and control access to classes and their members.

Think of a package as a folder for related Java classes. As your projects become larger, packages become extremely useful for keeping everything organized.