Navigation
Java Full Course: Mastering the Language Packages in Java
Packages in Java
1. What is a Package?
A package is a namespace that groups related classes, interfaces, enums, and annotations. It serves two main purposes:
- Organization – Keeps code structured and makes it easier to locate related types.
- Access control – Provides a visibility level (package‑private) that is accessible only within the same package.
Packages also help avoid naming conflicts. For example, you can have a com.example.Customer class and a com.other.Customer class without collision.
2. Creating Packages
a) The package Statement
To declare a class inside a package, you use the package keyword at the very top of the source file (before any imports or class definitions).
- The
packagestatement must be the first line (except comments). - Only one
packagestatement per source file. - If omitted, the class belongs to the default package (no package name). Using the default package is discouraged for anything beyond trivial examples.
b) Directory Structure
The Java compiler and runtime map package names to directory structures. A class com.example.myapp.MyClass must be stored in a directory hierarchy: com/example/myapp/MyClass.java (or .class).
Example structure:
When compiling from the root of the source tree:
The compiled .class files will be placed in corresponding directories, preserving the package structure.
c) Multiple Classes in One File
A single .java file can contain only one public class (with the same name as the file), but it can contain additional non‑public classes. All classes in that file belong to the same package.
3. Importing Packages
Once classes are organized in packages, you need a way to refer to them from other packages. Java provides the import statement to avoid writing fully qualified names repeatedly.
a) Fully Qualified Name
You can always use the full package path:
This becomes cumbersome for frequently used classes.
b) Import Statement
The import statement allows you to use the simple name of a class or interface.
c) Importing All Classes from a Package
Use * to import all classes from a package (but not sub‑packages).
This does not cause performance overhead; it simply makes all public types in that package available by simple name.
d) Static Imports (Java 5+)
Static import allows you to import static members (fields and methods) so you can use them without the class name.
You can also import all static members:
e) Implicitly Imported Packages
java.langis automatically imported for every class (so you can useString,System,Math, etc.).- No other packages are automatically imported.
f) Import Ambiguity
If two packages have a class with the same name, you cannot import both with * and use the simple name. You must either:
- Use fully qualified names for the conflicting classes.
- Import one class explicitly and use fully qualified for the other.
4. Package Naming Conventions
Java has well‑established naming conventions to ensure uniqueness and readability.
- a) Reverse Domain Name: To create globally unique package names, developers are encouraged to use a reversed internet domain name (which is unique). For example, if your domain is
example.com, package names start withcom.example.com.example.myapporg.apache.commons.lang3
- b) Lowercase Letters: Package names should be entirely lowercase. Avoid underscores and other characters; if a natural separator is needed, use another word (e.g.,
myappnotmy_app). - c) Hierarchical Structure: Packages often reflect the module or component structure. For example:
com.example.project.module.submodule - d) Standard Prefixes:
java.*: core Java packages (reserved)javax.*: extension packages (formerly optional)org.*: for organizationscom.*: for commercial entities
- e) Avoid Default Package: Never put classes in the default package (no package statement) for anything beyond quick experiments. It leads to naming collisions and prevents proper access control.
5. Access Protection with Packages
Access modifiers (public, protected, default, private) interact with packages to define visibility.
| Modifier | Same Class | Same Package | Subclass (different package) | Any Class |
|---|---|---|---|---|
private | ✅ | ❌ | ❌ | ❌ |
(default / package‑private) | ✅ | ✅ | ❌ | ❌ |
protected | ✅ | ✅ | ✅ | ❌ |
public | ✅ | ✅ | ✅ | ✅ |
- default (no modifier) – also called package‑private. Only accessible within the same package. This is the key access level tied to packages.
- protected – accessible within same package and also in subclasses (even if the subclass is in a different package).
- public – accessible everywhere.
- private – accessible only in the same class.
a) Example of Package‑Private Access
b) Protected and Inheritance
protected members are accessible in subclasses even across packages.
c) Why Package‑Private Matters
Package‑private allows you to keep internal implementation details hidden from outside packages while still allowing close collaboration among classes within the same package. This is often used for internal utility classes or for frameworks where certain classes are meant to be used only within the module.
6. Complete Example
Below is a small example that demonstrates packages, imports, and access protection.
Directory structure:
File: com/example/geometry/Shape.java
File: com/example/geometry/Circle.java
File: com/example/geometry/Rectangle.java
File: com/example/app/Main.java
7. Key Points to Remember
[!NOTE]
packagestatement defines the package; must be the first line (except comments).- Package names should be lowercase.
- The directory structure must mirror the package hierarchy.
importstatements let you use simple class names;import staticimports static members.java.langis automatically imported.- Default (package‑private) access restricts visibility to classes within the same package.
protectedadds inheritance across packages.- Avoid the default package; always place code in named packages for large projects.
