Java Packages
Declare a package at the beginning of the Java source file with package package_name;.
Asking Where a Class Belongs
When you open a Java class for the first time, it helps to ask one question before asking what the class does: where does this class belong? Java places every class inside a package. A package is a named container for related classes and interfaces, so it gives each Java type a stated organizational home.
A package is not an action that someone performs on a class later. It is the class's declared home. Once you know that home, you can work out whether another Java file needs an import directive to use the class, and you can work out exactly what name the class must be called by when you run it from the command line. This article follows one packaged program from its source file through compilation and execution, and then shows how to find the step where a package problem began.
What a Package Contains
A Java package is a collection of related classes and interfaces. Packages are named containers for related Java classes and interfaces.
The standard Java library uses this same idea. String and System are standard classes, and they are stored in named packages; both live in java.lang. The name of the package is part of the identity of the class, so the same simple name can exist in different packages without the two classes being confused, as long as their full names differ.
Declaring a Package in a Source File
A package is declared at the beginning of a Java source file. The declaration uses the package keyword, followed by the package name and a semicolon. The general form is package package_name; where package_name is the dotted name you want the class to belong to. Package parts separated by periods become nested directories on disk, which is why the declaration matters beyond the file itself.
- The package line comes first in the file, before any class declaration.
- com.example.util is the package name; each dot marks a nested level.
- Helper is the class name, and its full name is com.example.util.Helper.
What do you think happens?
If this file has no package line at all, which package does the class Helper belong to?
Reveal answer
The default package.
Omitting a package declaration places a class in the default package. Java still places the class somewhere; it simply has no named package.
Tracing the Directory Structure
The package name and the folder layout must agree. The package com.example.util corresponds to the nested folders com, then example, then util. The source file Helper.java must sit inside the util folder. Think of the dotted name as a path to read from left to right: each part is one folder, and the file sits at the bottom of that path.
Placing a Second Class in a Second Package
You want a class Main in package com.example.app that uses Helper from com.example.util. Where do the two source files go, relative to the project root?
- 1Read the package name of Main
The declaration package com.example.app; means the parts are com, example, and app.
- 2Build the folder path
Each part becomes one folder, so the path is com/example/app/.
- 3Place the file
Main.javagoes inside com/example/app/, directly in the app folder. - 4Repeat for the other package
Helper.javagoes inside com/example/util/, which shares the com/example prefix but lives in its own util folder.
project/com/example/app/Main.java and project/com/example/util/Helper.java. Both files share the com/example ancestors, and each sits in the folder that matches its own package.
Choosing the Compilation Path
Compilation and execution use different forms of the package name, and this is the step where many learners get confused. For compilation, you compile from the main Java working directory, which is the directory that contains the top-level package folder (here, project). You then include the source file's directory path in the javac command, so that the compiler is told exactly where the file sits.
- cd moves into the main working directory that holds the com folder.
- Each argument is the directory path to a source file, using folder separators, not dots.
- Both files are compiled in one command because Main uses Helper.
Running with a Fully Qualified Class Name
Execution does not use the directory path. Instead, you name the class with its fully qualified class name: the package name, then a period, then the class name. The execution command for the Main class is written with dots throughout, not folder separators, and it is run from the same main working directory used for compilation.
Hello, IJK- The command word java starts the program.
- com.example.app is the package part; the dots are part of the package name.
- Main is the class name, separated from the package by a period.
Named Packages Versus the Default Package
A class with a package declaration belongs to a named package. A class with no package declaration is placed in the default package. The default package is convenient for very small beginner exercises because no package name has to be written at the top of the file. However, official Java style guidelines discourage using it, so for real code a named package is the expected choice.
| Feature | Named package | Default package |
|---|---|---|
| Package declaration | Present at the top of the file, such as package com.example.util; | Omitted |
| Folder structure | Must match the dotted package name | No package folders are required by the declaration |
| Style guidance | The expected choice for real code | Discouraged by official Java style guidelines |
| Class name in execution | Fully qualified, such as com.example.util.Helper | Simple class name |
Differences between a class in a named package and a class in the default package.
Why a Class from Another Package Needs an Import
The package declaration answers the question where this class belongs. An import directive answers a different question: how does this file use a class that belongs to another package? In the Main example above, Main sits in com.example.app and uses Helper from com.example.util. Without an import, Main would have to refer to Helper by its full name every time. The import directive lets Main use the simple name Helper.
Hello, IJK- The package line states Main's own home.
- The import line brings Helper from another package into scope by its full name.
- Helper.greet is called by its simple name because of the import.
Finding Which Step Failed
When a packaged program fails, do not guess. Work through the four places a package problem can start, in order: the declaration, the directory structure, the compilation command, and the execution command. The key debugging question is where the expected result first diverges from what actually happened.
A teammate has put package com.example.util; at the top of Helper.java, but the file is saved directly in the project root, not in a util folder. They report that the program will not run with java com.example.app.Main. Using the flowchart, which step should you check first, and what change would you make to the folders or to the declaration?
Hints
- Start with the declaration: does the package line agree with where the file sits?
- The package com.example.util corresponds to three nested folders, and the file must be inside the last one.
- Decide whether the fix belongs in the folder structure or in the package line, and think about which one the program's package name requires.
Mistakes That Break Packaged Programs
Common mistake Writing the package line after the class declaration
What it looks likepublic class Helper { } followed by package com.example.util; below itWhy it failsThe package declaration belongs at the beginning of the source file.
Do this insteadPlace package com.example.util; as the first line of the file.
Common mistake Putting the file in a folder that does not match the package name
What it looks likeHelper.java with package com.example.util; saved directly in the project root
Why it failsPackage parts separated by periods become nested directories, so the folders and the declaration disagree.
Do this insteadCreate com/example/util/ and save Helper.java inside the util folder.
Common mistake Using dots in the compilation path
What it looks likejavac com.example.util.Helper.java
Why it failsThe compilation command names the source file through its directory path, not through the dotted package name.
Do this insteadUse javac com/example/util/Helper.java, or the backslash form on Windows.
Common mistake Using a folder path in the execution command
What it looks likejava com/example/app/Main
Why it failsExecution uses the fully qualified class name, with periods between package and class names.
Do this insteadUse java com.example.app.Main.Common mistake Assuming every class needs an import
What it looks likeUsing a class from another package with no import and no full name
Why it failsA class from another package generally needs an import directive, so the compiler cannot find the simple name.
Do this insteadAdd an import line such as import com.example.util.Helper; or use the full name.
Key Takeaways
- Every Java class belongs to a package, which is a named container for related classes and interfaces; the package keyword at the top of a source file declares that home.
- Package parts separated by periods become nested directories, so the folder structure must match the package name, and the source file must sit in the innermost folder.
- Compilation uses the directory path of the source file from the main working directory, while execution uses the fully qualified class name with periods, such as java com.example.app.Main.
- A class without a package declaration goes to the default package, which official Java style guidelines discourage, and a class from another package generally needs an import directive, with
java.langclasses as the automatic exception. - When a packaged program fails, check the declaration, the directory structure, the javac command, and the java command in that order to find where the expected result first diverges.