SECTION 1
Historical Context & Motivation
As software projects grew from a few hundred lines to millions of lines of code throughout the 1980s and 1990s, developers faced a serious organizational problem. Imagine writing a school essay where every paragraph, heading, and footnote lived in a single document with no folders or file structure — finding anything would become nearly impossible. Early programming languages like C let you group code into separate files, but there was no built-in system for preventing two files from accidentally using the same name. When James Gosling and the team at Sun Microsystems designed Java in the mid-1990s, they solved this problem by building packages directly into the language.
1991 • Project Green Begins
1995 • Java 1.0 Released
java.lang and java.io, demonstrating the convention of grouping related classes together.1998 • Java 2 & Enterprise Growth
com.sun.java) becomes standard to prevent naming conflicts across organizations worldwide.2017 • Java 9 Module System
The central question that packages answer is straightforward: How do you organize thousands of classes so that names don't collide and developers can find what they need? This lesson will teach you how to create packages, import classes from them, and follow the naming conventions that professional Java developers use every day.
SECTION 2
Core Principles & Definitions
A package in Java is a named group of related classes and interfaces that provides a separate namespace — a way to guarantee that class names don't conflict. Think of a package like a folder on your computer. You can have a file called notes.txt in your English folder and another notes.txt in your History folder without any confusion, because the folder path makes each file unique. Packages work the same way for Java classes.
Namespace Separation
Date class in java.util is entirely separate from a Date class in java.sql.Logical Organization
java.io.Access Control
Reverse-Domain Convention
com.google.maps) to ensure global uniqueness.KEY TAKEAWAY
com.myschool.projects.Calculator uniquely identifies your Calculator class even if a thousand other developers also wrote one. The package is the "full address" that makes each class name globally unique.SECTION 3
Visual Explanation — Package Hierarchy
package declaration at the top of each Java file. Notice that com.myschool.math maps to the folder path com/myschool/math/.The diagram above reveals the most important rule of Java packages: the package name must exactly match the folder path where the source file lives. If you declare package com.myschool.math; at the top of a file, that file must be saved inside the folder com/myschool/math/. If there is a mismatch, the Java compiler will throw an error. This tight coupling between folders and packages is what keeps large codebases navigable.
Important Rule
package statement must be the very first line of code in your Java file (comments and blank lines above it are fine). Only one package declaration is allowed per file, and every class in that file belongs to that package.SECTION 4
How Packages Work — Syntax & Import Statements
Declaring a Package
Every Java source file can begin with a package declaration, which tells the compiler which package the file belongs to. The syntax is simple:
PACKAGE DECLARATION SYNTAX
Each segment is separated by a dot, uses only lowercase letters, and matches a folder in the file system. For example: package com.myschool.math;
Importing Classes from Other Packages
When you want to use a class from a different package, you have three options. The most common is the import statement, which appears after the package declaration and before the class definition. You can import a single class or use a wildcard to import all classes from a package.
SINGLE-CLASS IMPORT
Imports only the Calculator class. This is the preferred style because it makes dependencies explicit.
WILDCARD IMPORT
Imports all classes in the com.myschool.math package. Convenient but can make it harder to see which classes are actually being used.
FULLY QUALIFIED NAME (NO IMPORT NEEDED)
You can always use the full package path directly in code. This is useful when two imported packages contain classes with the same name, such as java.util.Date and java.sql.Date.
Free Package
java.lang package is automatically imported into every Java program. That's why you can use String, System, Math, and other fundamental classes without writing an import statement.SECTION 5
Package Naming Conventions in Detail
Java's naming conventions aren't enforced by the compiler — you won't get an error for using uppercase letters in a package name. However, following these conventions is considered essential in professional development because they prevent naming collisions and make code instantly readable to other developers. The key convention is the reverse internet domain name pattern.
| Convention | Good Example | Bad Example |
|---|---|---|
| All lowercase | com.myschool.math | Com.MySchool.Math |
| Reverse domain name | org.apache.commons | commons.apache.org |
| No hyphens (use underscores) | com.my_school.app | com.my-school.app |
| Avoid Java keywords | com.example.my_int | com.example.int |
| Meaningful names | com.school.gradebook | com.school.stuff |
Common package naming conventions with examples
SECTION 6
Worked Example — Building a School Project with Packages
Let's walk through creating a complete project that uses packages. Imagine you're building a grade calculator application for your school. You want to separate the math logic from the user interface code.
Creating a Multi-Package School Project
- 1
Step 1 — Plan Your Package Structure
Decide how to organize your classes. We'll create two packages:com.school.grades.logicfor calculation classes andcom.school.grades.uifor the user interface. This means we need two sets of folders.Folder structure:src/com/school/grades/logic/andsrc/com/school/grades/ui/ - 2
Step 2 — Create the GradeCalculator Class
Create a file calledGradeCalculator.javainsidesrc/com/school/grades/logic/. The first line must declare the package:package com.school.grades.logic; public class GradeCalculator { public double average(double[] scores) { double sum = 0; for (double s : scores) { sum += s; } return sum / scores.length; } } - 3
Step 3 — Create the Main Application Class
CreateApp.javainsidesrc/com/school/grades/ui/. This class needs to importGradeCalculatorfrom the other package:package com.school.grades.ui; import com.school.grades.logic.GradeCalculator; public class App { public static void main(String[] args) { GradeCalculator calc = new GradeCalculator(); double[] scores = {92, 85, 78, 96, 88}; System.out.println("Average: " + calc.average(scores)); } } - 4
Step 4 — Compile from the Source Root
Navigate to thesrcdirectory and compile both files. The compiler needs to be able to find all referenced packages from this root directory.javac com/school/grades/logic/GradeCalculator.java javac com/school/grades/ui/App.java - 5
Step 5 — Run the Application
Run the program using the fully qualified class name (the package name plus the class name). Java uses this to locate the correct.classfile.java com.school.grades.ui.AppOutput: Average: 87.8
SECTION 7
Package Types — Built-in vs. User-Defined
Java packages fall into two broad categories. The built-in packages ship with the Java Development Kit (JDK) and provide ready-made functionality. The user-defined packages are the ones you create yourself to organize your own code. Understanding both types is essential for writing well-structured Java programs.
| Feature | Built-in Packages | User-Defined Packages |
|---|---|---|
| Source | Included with the JDK | Created by the developer |
| Examples | java.util, java.io, java.lang | com.school.grades, org.club.roster |
| Import needed? | Yes (except java.lang) | Yes, when accessing from other packages |
| Naming | Starts with java. or javax. | Starts with reversed domain (e.g., com.) |
| Purpose | Standard functionality: data structures, I/O, networking | Custom application logic specific to your project |
Comparison of built-in and user-defined Java packages
KEY TAKEAWAY
SECTION 8
Connection to Modules and Advanced Organization
Packages are the foundation of code organization in Java, but as applications scale to millions of lines, even packages can become difficult to manage. Java 9 introduced the module system (also called Project Jigsaw), which groups related packages together into a higher-level unit. Think of it this way: if packages are folders, modules are like labeled boxes that hold multiple folders and explicitly list which folders are visible to the outside world.
| Concept | Package | Module (Java 9+) |
|---|---|---|
| Granularity | Groups related classes | Groups related packages |
| Defined by | package declaration in each file | module-info.java descriptor file |
| Access control | Package-private (default) or public | Exports specific packages; hides internal ones |
| Required to learn first? | Yes — fundamental | No — typically covered in advanced courses |
Packages vs. Modules in Java
For now, focus on mastering packages. Once you're comfortable with them, modules will feel like a natural extension. The good news is that packages you create today will work perfectly inside modules later — nothing about the package system changes when modules are added on top.
SECTION 9
Practice Problems
Question 1: CONCEPTUAL
Timer without causing a conflict, as long as they are in different packages. What mechanism makes this possible?Show answer
javax.swing.Timer vs. java.util.Timer). Even though the simple class name is the same, the full name is different. The Java compiler and runtime use the fully qualified name to identify classes, so there is no ambiguity.Question 2: BASIC CALCULATION
coolprojects.org. They are building a chess game with separate packages for the board logic and the AI. Write the correct package declarations and the folder paths (from the source root) for a class called Board.java in the board package and MoveGenerator.java in the AI package.Show answer
package org.coolprojects.chess.board; and live at the path src/org/coolprojects/chess/board/Board.java. The AI class would use package org.coolprojects.chess.ai; and live at src/org/coolprojects/chess/ai/MoveGenerator.java. Notice the domain is reversed (org.coolprojects instead of coolprojects.org) and all letters are lowercase.Question 3: INTERMEDIATE
import com.school.utils.StringHelper;
package com.school.app;
public class Main {
public static void main(String[] args) {
StringHelper helper = new StringHelper();
}
}Show answer
package statement must come before the import statement — it must always be the first line of code. Second, the order must be: package declaration, then imports, then class definition. The corrected version swaps the first two lines:
package com.school.app;
import com.school.utils.StringHelper;
public class Main {
public static void main(String[] args) {
StringHelper helper = new StringHelper();
}
}Question 4: APPLIED
Book, Member, Checkout, DatabaseConnection, and SearchService. Your school's domain is lincoln-high.edu. Design a package structure by grouping related classes, writing the package name for each group, and explaining why you chose that grouping.Show answer
edu.lincoln_high.library.model for data classes like Book and Member (note the underscore replacing the hyphen in the domain name). Second, edu.lincoln_high.library.service for business logic classes like Checkout and SearchService. Third, edu.lincoln_high.library.data for DatabaseConnection. This separation follows the common pattern of dividing code by responsibility: models hold data, services contain logic, and data classes handle storage. Each package groups classes that change for the same reasons.Question 5: CRITICAL THINKING
import java.util.*; to bring in all classes from a package. However, most professional style guides (like Google's Java Style Guide) discourage wildcard imports. What problems could wildcard imports cause, especially as a project grows? Consider what happens when a new class is added to a package you're wildcard-importing.Show answer
java.util.* and java.sql.*, and both contain a class named Date, the compiler won't know which one you mean, causing an ambiguity error. Second, if a library you depend on adds a new class in a future version that happens to have the same name as one of your classes, your code could break without you changing anything. Third, wildcard imports make it harder for someone reading your code to know exactly which classes are being used, reducing readability. Explicit single-class imports avoid all these issues by making dependencies clear and preventing accidental name collisions.SUMMARY
Lesson Summary
Summary
Java packages are named groups of related classes that provide namespace separation, logical organization, and access control. Every package name must match its folder path on disk, and the package declaration must be the first line of code in each Java file. To use classes from other packages, you write import statements — either single-class imports (preferred) or wildcard imports.
The standard naming convention uses a reversed internet domain name followed by project and module segments, all in lowercase letters separated by dots (e.g., com.myschool.math). Built-in packages like java.util and java.io ship with the JDK, while user-defined packages let you organize your own code. As projects grow, Java 9's module system adds an additional layer above packages for even larger-scale organization.