Packages in Java
Learn Packages in Java in detail, including built-in packages, user-defined packages, package declarations, imports, subpackages, access control, static imports, naming conventions, project structure, compilation, JAR files, and real-world package organization.
Introduction
As Java applications grow, placing every class in one location quickly becomes difficult to manage. Packages solve this problem by organizing related classes, interfaces, enums, records, and other types into meaningful groups.
package com.programinds.student;
public class Student {
private String name;
public Student(String name) {
this.name = name;
}
public String getName() {
return name;
}
}Packages are a fundamental part of Java application structure. Almost every professional Java project uses packages to organize source code, prevent naming conflicts, control accessibility, and create maintainable software architectures.
- What a package is.
- Why packages are important.
- How packages organize Java code.
- The difference between built-in and user-defined packages.
- Common packages in the Java API.
- How java.lang works.
- How java.util is used.
- How java.io and java.nio are used.
- How java.time is used.
- How java.net is used.
- How java.sql is used.
- How to create a user-defined package.
- How to write a package declaration.
- The rules of the package statement.
- How package names map to directories.
- How to compile packaged classes.
- How to run packaged classes.
- How the javac -d option works.
- How to use classes from another package.
- What a fully qualified class name is.
- How the import statement works.
- How to import one class.
- How wildcard imports work.
- What Java imports automatically.
- How import conflicts occur.
- How classes in the same package interact.
- What subpackages are.
- Why parent and child packages are independent.
- How to create subpackages.
- Java package naming conventions.
- Why reverse domain names are used.
- How access modifiers interact with packages.
- How public access works.
- How default access works.
- How protected access works.
- How private access works.
- What package-private access means.
- Rules for public classes.
- Rules for Java source file names.
- How multiple classes can exist in one source file.
- What static import is.
- How to import static members.
- When static imports should be used.
- How to organize application packages.
- The difference between layer-based and feature-based structures.
- How packages are structured in small projects.
- How packages are structured in large projects.
- How IDEs manage packages.
- How packages fit into Maven projects.
- How packages fit into Gradle projects.
- What the default package is.
- Why professional applications avoid the default package.
- How packages relate to the classpath.
- What the classpath is.
- How packages are stored in JAR files.
- How to create a JAR file.
- How to use classes from a JAR file.
- What executable JAR files are.
- How packages relate to Java modules.
- What package-info.java is.
- How packages are used in real-world applications.
- Common package errors.
- Package best practices.
What is a Package?
A package is a namespace that groups related Java types together. These types can include classes, interfaces, enums, records, and annotations.
APPLICATION
├── com.programinds.student
│
│ ├── Student
│ ├── StudentService
│ └── StudentRepository
│
├── com.programinds.course
│
│ ├── Course
│ ├── CourseService
│ └── CourseRepository
│
└── com.programinds.payment
├── Payment
├── PaymentService
└── PaymentGatewayInstead of storing every class in one large group, packages divide an application into logical sections based on responsibility, feature, layer, or domain.
Why Packages are Important
Organization
Packages group related classes and other types into meaningful sections.
Name Management
Different packages can contain classes with the same simple name.
Access Control
Packages work with access modifiers to control which classes and members are accessible.
Reusability
Well-organized packages make reusable components easier to distribute and use.
Modularity
Large applications can be divided into smaller logical units.
Maintenance
Developers can locate, understand, test, and modify related code more easily.
Real-World Analogy
Think of a package like a department inside a large company. Employees are grouped according to their responsibilities instead of everyone working in one giant room.
COMPANY
├── HUMAN RESOURCES
│
│ ├── Recruiter
│ ├── HRManager
│ └── PayrollOfficer
│
├── FINANCE
│
│ ├── Accountant
│ ├── Auditor
│ └── FinanceManager
│
└── TECHNOLOGY
├── Developer
├── Tester
└── SystemAdministrator
JAVA APPLICATION
├── hr package
├── finance package
└── technology packageThe company remains one organization, but departments make responsibilities clearer. Java packages provide the same kind of organization for source code.
Package Structure
com.programinds
│
├── user
│ │
│ ├── User
│ └── UserService
│
├── course
│ │
│ ├── Course
│ └── CourseService
│
└── payment
│
├── Payment
└── PaymentServiceA package name commonly contains multiple parts separated by dots. Each part usually corresponds to a directory in the source structure.
Types of Packages
JAVA PACKAGES
├── BUILT-IN PACKAGES
│
│ Provided by Java
│
│ Examples:
│
│ java.lang
│ java.util
│ java.io
│ java.time
│
└── USER-DEFINED PACKAGES
Created by developers
Examples:
com.programinds.user
com.programinds.course
com.programinds.paymentBuilt-in Packages
The Java platform provides a large standard library organized into built-in packages. These packages contain reusable classes and interfaces for common programming tasks.
import java.util.ArrayList;
import java.time.LocalDate;
public class Main {
public static void main(
String[] args
) {
ArrayList<String> names =
new ArrayList<>();
names.add("Aarav");
LocalDate today =
LocalDate.now();
System.out.println(names);
System.out.println(today);
}
}Common Java Packages
java.lang
Core language classes
java.util
Utility classes
and collections
java.io
Traditional input
and output
java.nio
Modern file and
buffer operations
java.time
Date and time API
java.net
Networking
java.sql
Database access
java.math
Large and precise
numeric calculations
java.text
Text and number formatting
java.security
Security-related APIsThe java.lang Package
The java.lang package contains fundamental classes required by almost every Java program. Java imports this package automatically.
String message = "Hello";
Integer number = 100;
Double price = 99.99;
System.out.println(message);
Math.sqrt(25);
Thread thread;String
Object
System
Math
Integer
Double
Boolean
Character
StringBuilder
StringBuffer
Thread
Exception
RuntimeException- You do not need to write import java.lang.String.
- You do not need to write import java.lang.System.
- You do not need to write import java.lang.Math.
- The java.lang package is automatically available.
The java.util Package
The java.util package contains many general-purpose utility classes and important collection types.
import java.util.ArrayList;
import java.util.Scanner;
public class Main {
public static void main(
String[] args
) {
Scanner scanner =
new Scanner(System.in);
ArrayList<String> names =
new ArrayList<>();
names.add("Aarav");
names.add("Diya");
System.out.println(names);
}
}Scanner
ArrayList
LinkedList
HashSet
HashMap
Collections
Arrays
Optional
Random
UUIDThe java.io Package
The java.io package provides traditional input and output classes for files, streams, readers, writers, and serialization.
import java.io.File;
public class Main {
public static void main(
String[] args
) {
File file =
new File(
"data.txt"
);
System.out.println(
file.exists()
);
}
}The java.nio Package
The java.nio package family provides modern APIs for files, paths, channels, and buffers.
import java.nio.file.Path;
public class Main {
public static void main(
String[] args
) {
Path path =
Path.of(
"data.txt"
);
System.out.println(path);
}
}The java.time Package
The java.time package provides the modern Java date and time API.
import java.time.LocalDate;
import java.time.LocalDateTime;
public class Main {
public static void main(
String[] args
) {
LocalDate today =
LocalDate.now();
LocalDateTime now =
LocalDateTime.now();
System.out.println(today);
System.out.println(now);
}
}The java.net Package
The java.net package contains classes used for networking, URLs, URIs, sockets, and related operations.
import java.net.URI;
public class Main {
public static void main(
String[] args
) {
URI website =
URI.create(
"https://example.com"
);
System.out.println(
website.getHost()
);
}
}The java.sql Package
The java.sql package contains core JDBC APIs used to communicate with relational databases.
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;User-Defined Packages
A user-defined package is a package created by a developer to organize application code.
com.programinds
├── model
├── service
├── repository
├── controller
├── exception
├── configuration
└── utilityCreating a Package
package com.programinds.student;
public class Student {
public void display() {
System.out.println(
"Student information"
);
}
}The package statement tells Java that the Student class belongs to the com.programinds.student package.
Package Declaration
package packageName;package student;
package com.programinds;
package com.programinds.course;
package com.programinds.payment.service;Package Statement Rules
- A source file can contain at most one package declaration.
- The package declaration must appear before import statements.
- Only comments and whitespace may appear before the package declaration.
- The package name should match the intended directory structure.
- Package names are case-sensitive.
- Professional package names are normally written in lowercase.
- The package declaration ends with a semicolon.
package com.programinds.student;
import java.util.ArrayList;
public class Student {
}1. PACKAGE DECLARATION
2. IMPORT STATEMENTS
3. TYPE DECLARATIONSPackage and Directory Structure
Package names normally correspond to directories. Each dot in the package name represents another directory level.
package com.programinds.student;src
└── com
└── programinds
└── student
└── Student.javaPACKAGE
com.programinds.student
DIRECTORIES
com
│
└── programinds
│
└── studentCompiling Packaged Classes
package com.programinds.student;
public class Student {
public static void main(
String[] args
) {
System.out.println(
"Student class"
);
}
}javac Student.javaFor manual compilation, the class file must ultimately be placed in a directory structure matching the declared package.
Running Packaged Classes
java com.programinds.student.Student- Run the class from the package root.
- Use the fully qualified class name.
- Do not run it as java Student when it belongs to a named package.
- The classpath must contain the package root.
The javac -d Option
The -d option tells the Java compiler where to place generated class files. The compiler creates the required package directory structure automatically.
javac -d . Student.java.
└── com
└── programinds
└── student
└── Student.classUsing Classes from Another Package
package com.programinds.model;
public class Student {
public void display() {
System.out.println(
"Student"
);
}
}package com.programinds.app;
import com.programinds.model.Student;
public class Main {
public static void main(
String[] args
) {
Student student =
new Student();
student.display();
}
}Fully Qualified Class Name
A fully qualified class name contains the complete package name followed by the class name.
java.lang.String
java.util.Scanner
java.util.ArrayList
java.time.LocalDate
com.programinds.model.Studentpublic class Main {
public static void main(
String[] args
) {
java.util.ArrayList<String> names =
new java.util.ArrayList<>();
names.add("Aarav");
System.out.println(names);
}
}The import Statement
An import statement allows a type from another package to be referenced using its simple name instead of its fully qualified name.
java.util.Scanner scanner =
new java.util.Scanner(
System.in
);import java.util.Scanner;
Scanner scanner =
new Scanner(System.in);- It allows the compiler to resolve a simple type name.
- It improves source code readability.
- It does not copy source code.
- It does not load every imported class into memory.
- It does not create an object.
Importing a Single Class
import java.util.Scanner;
public class Main {
public static void main(
String[] args
) {
Scanner scanner =
new Scanner(System.in);
}
}Wildcard Imports
import java.util.*;The wildcard allows types directly inside the specified package to be referenced without individual imports.
import java.util.*;
public class Main {
public static void main(
String[] args
) {
Scanner scanner =
new Scanner(System.in);
ArrayList<String> names =
new ArrayList<>();
HashMap<Integer, String> students =
new HashMap<>();
}
}Single Import vs Wildcard Import
SINGLE IMPORT
import java.util.Scanner;
Advantages
Clear dependency
Easy to see what is used
Commonly preferred by IDEs
WILDCARD IMPORT
import java.util.*;
Advantages
Shorter import section
when many package types are used
IMPORTANT
Wildcard import does not import
subpackage typesAutomatic Imports
Java automatically makes certain types available without explicit import statements.
1. TYPES IN THE SAME PACKAGE
2. TYPES IN java.lang
EXAMPLES
String
System
Math
Object
Integer
DoubleImport Rules
- Import statements appear after the package declaration.
- Import statements appear before class declarations.
- Types in java.lang do not require explicit imports.
- Types in the same package do not require imports.
- A wildcard imports types directly inside one package.
- A wildcard does not recursively import subpackages.
- Importing a class does not create an object.
- Importing a package does not copy its code.
- Unused imports may produce IDE warnings.
- Conflicting simple class names may require fully qualified names.
Import Name Conflicts
Two different packages can contain classes with the same simple name.
java.util.Date
java.sql.Dateimport java.util.Date;
public class Main {
public static void main(
String[] args
) {
Date utilityDate =
new Date();
java.sql.Date databaseDate =
java.sql.Date.valueOf(
"2026-07-10"
);
}
}Same Package Access
Classes in the same package can refer to one another by simple name without import statements.
package com.programinds.student;
public class Student {
}package com.programinds.student;
public class StudentService {
Student student =
new Student();
}Subpackages
A package name can contain multiple hierarchical-looking levels separated by dots.
com.programinds
com.programinds.student
com.programinds.student.service
com.programinds.student.repositoryPackages are Independent
Java does not treat a subpackage as a member of its parent package for access or import purposes. Each package is a separate namespace.
com.programinds.student
AND
com.programinds.student.service
ARE DIFFERENT PACKAGES
THE SECOND NAME LOOKS NESTED
BUT JAVA ACCESS RULES
TREAT THEM AS
SEPARATE PACKAGES- Importing com.programinds.student.* does not import classes from com.programinds.student.service.
- A subpackage does not automatically gain package-private access to its parent package.
- A parent package does not automatically gain package-private access to its subpackage.
Creating Subpackages
package com.programinds.student.service;
public class StudentService {
}src
└── com
└── programinds
└── student
│
├── Student.java
│
├── service
│ └── StudentService.java
│
└── repository
└── StudentRepository.javaPackage Naming Conventions
- Use lowercase letters.
- Avoid spaces.
- Avoid hyphens.
- Use meaningful names.
- Use the reverse domain naming convention for globally unique packages.
- Use singular or consistent domain terms according to project standards.
- Avoid extremely long package names.
- Avoid generic package names such as stuff or misc.
- Organize packages according to application responsibilities.
GOOD
com.programinds.student
com.programinds.course
com.programinds.payment
POOR
StudentPackage
my-package
randomStuff
ABC
everythingReverse Domain Naming
Organizations commonly reverse their internet domain name when creating the root Java package. This helps reduce package name collisions.
DOMAIN
programinds.com
PACKAGE ROOT
com.programinds
DOMAIN
example.org
PACKAGE ROOT
org.example
DOMAIN
company.co.in
PACKAGE ROOT
in.co.companyPackage Naming Examples
com.programinds.user
com.programinds.course
com.programinds.payment
com.programinds.authentication
com.programinds.notification
com.programinds.common
com.programinds.configurationAccess Control and Packages
Packages work closely with Java access modifiers. Accessibility depends on both the modifier and the location of the accessing code.
public
protected
default
No modifier
privatepublic Access
A public class or member can be accessed from other packages when the containing type is also accessible.
package com.programinds.model;
public class Student {
public String name =
"Aarav";
}Default Access
When no access modifier is written, the type or member has package-private access. It is accessible only from the same package.
package com.programinds.model;
class StudentValidator {
}protected Access
A protected member is accessible within the same package and can also be accessed through inheritance from subclasses in other packages, subject to Java protected-access rules.
package com.programinds.model;
public class Person {
protected String name;
}private Access
A private member is accessible only inside the class that declares it. Being in the same package does not provide access to another class private members.
package com.programinds.model;
public class Student {
private int marks;
}Access Modifier Table
MODIFIER SAME CLASS SAME PACKAGE SUBCLASS OTHER PACKAGE
public YES YES YES YES
protected YES YES YES* NO
default YES YES NO NO
private YES NO NO NO
* Protected access from another package
follows inheritance-specific rulesPackage-Private Access
Package-private access is created by writing no access modifier. It is useful for implementation details that should be shared within one package but hidden from external packages.
package com.programinds.payment;
public class PaymentService {
void validatePayment() {
System.out.println(
"Validating payment"
);
}
}Public Classes
A top-level public class is accessible from other packages, provided its package is available and the class is imported or referenced by its fully qualified name.
package com.programinds.course;
public class Course {
}Class File Naming Rules
- A public top-level class name must match the source file name.
- public class Student must normally be stored in Student.java.
- Only one public top-level class is allowed per source file.
- A source file can contain additional non-public top-level classes.
Multiple Classes in One File
package com.programinds.student;
public class Student {
}
class StudentValidator {
}
class StudentMapper {
}Only Student is public. The other top-level classes are package-private and can be accessed only from the same package.
Static Import
Static import allows accessible static members to be referenced without writing the class name each time.
double result =
Math.sqrt(25);
System.out.println(
Math.PI
);import static java.lang.Math.PI;
import static java.lang.Math.sqrt;
public class Main {
public static void main(
String[] args
) {
double result =
sqrt(25);
System.out.println(PI);
}
}Importing Static Members
import static packageName.ClassName.memberName;import static java.lang.Math.max;
public class Main {
public static void main(
String[] args
) {
int largest =
max(10, 20);
System.out.println(largest);
}
}Wildcard Static Import
import static java.lang.Math.*;
public class Main {
public static void main(
String[] args
) {
System.out.println(
sqrt(25)
);
System.out.println(
pow(2, 3)
);
System.out.println(PI);
}
}When to Use Static Import
- Static import can reduce repetitive class names.
- It is useful for frequently used constants.
- It is common in testing libraries.
- Excessive static imports can make code origins unclear.
- Prefer readability over shorter code.
Package Organization
A package structure should help developers understand where code belongs and where related code can be found.
model
Domain objects
service
Business logic
repository
Data access
controller
Request handling
exception
Custom exceptions
configuration
Application configuration
utility
Shared helper codeLayer-Based Package Structure
com.programinds
├── controller
│ ├── UserController
│ └── CourseController
│
├── service
│ ├── UserService
│ └── CourseService
│
├── repository
│ ├── UserRepository
│ └── CourseRepository
│
└── model
├── User
└── CourseIn a layer-based structure, classes are grouped according to their technical responsibility.
Feature-Based Package Structure
com.programinds
├── user
│ ├── User
│ ├── UserController
│ ├── UserService
│ └── UserRepository
│
└── course
├── Course
├── CourseController
├── CourseService
└── CourseRepositoryIn a feature-based structure, code belonging to one business feature is grouped together.
Layer-Based vs Feature-Based Packages
LAYER-BASED
Group by technical role
controller
service
repository
model
FEATURE-BASED
Group by business feature
user
course
payment
notification
CHOICE DEPENDS ON
Project size
Team structure
Application architecture
Domain complexity
Maintenance requirementsSmall Project Structure
com.programinds.library
├── model
│ ├── Book
│ └── Member
│
├── service
│ └── LibraryService
│
└── app
└── MainLarge Project Structure
com.programinds
├── authentication
│ ├── controller
│ ├── service
│ ├── model
│ └── repository
│
├── user
│ ├── controller
│ ├── service
│ ├── model
│ └── repository
│
├── course
│ ├── controller
│ ├── service
│ ├── model
│ └── repository
│
├── payment
│ ├── controller
│ ├── service
│ ├── model
│ └── repository
│
└── common
├── exception
├── configuration
└── utilityPackages in IDEs
Modern IDEs such as IntelliJ IDEA, Eclipse, and VS Code with Java extensions can create package directories, add package declarations, organize imports, and move classes between packages.
src
└── com.programinds
│
├── model
│ └── Student
│
├── service
│ └── StudentService
│
└── app
└── Main- An IDE may display nested directories as one dotted package name.
- The underlying package structure still maps to directories.
- Use refactoring tools when moving classes between packages.
- Refactoring tools can update package declarations and imports automatically.
Packages in Maven Projects
project
└── src
│
├── main
│ └── java
│ └── com
│ └── programinds
│ ├── model
│ ├── service
│ └── app
│
└── test
└── java
└── com
└── programindsIn a standard Maven project, production Java source files are normally stored under src/main/java and test source files under src/test/java.
Packages in Gradle Projects
Gradle Java projects commonly use the same standard source directory structure as Maven.
src
├── main
│ ├── java
│ │ └── com
│ │ └── programinds
│ │
│ └── resources
│
└── test
├── java
│ └── com
│ └── programinds
│
└── resourcesThe Default Package
A Java class without a package declaration belongs to the unnamed package, commonly called the default package.
public class Main {
public static void main(
String[] args
) {
System.out.println(
"No package declaration"
);
}
}Why Avoid the Default Package?
- The default package provides poor organization.
- It does not scale well.
- Types in named packages cannot import types from the unnamed package.
- Frameworks and build tools expect organized package structures.
- Large applications require clear namespaces.
- Professional Java projects should use named packages.
Packages and the Classpath
The Java compiler and JVM must know where to find package roots and compiled classes. The classpath provides this search path.
CLASSPATH ROOT
.
PACKAGE
com.programinds.student
JVM LOOKS FOR
./com/programinds/student/Student.classWhat is Classpath?
The classpath is a list of locations where Java tools search for compiled classes and other classpath resources.
CLASSPATH CAN INCLUDE
Directories
JAR files
Multiple locationsSetting the Classpath
javac -cp classes Main.javajava -cp classes com.programinds.Main-cp
AND
-classpath
MEAN THE SAME THINGPackages and JAR Files
A JAR file is an archive that can contain compiled Java packages, classes, resources, and metadata.
application.jar
├── META-INF
│ └── MANIFEST.MF
│
└── com
└── programinds
├── model
│ └── Student.class
│
└── service
└── StudentService.classCreating a JAR File
jar --create --file application.jar -C classes .The package directory structure is preserved inside the JAR file.
Using Classes from a JAR File
javac -cp library.jar Main.javajava -cp library.jar;. Main- Windows commonly uses a semicolon between classpath entries.
- Linux and macOS commonly use a colon between classpath entries.
- Build tools usually manage classpaths automatically.
Executable JAR Files
A JAR file can specify a main class and be launched using the java -jar command.
java -jar application.jarPackages and Modules
Packages organize related Java types. Java modules operate at a higher level and group packages while defining dependencies and exported packages.
MODULE
└── PACKAGES
└── TYPES
EXAMPLE
MODULE
com.programinds.app
PACKAGES
com.programinds.user
com.programinds.course
com.programinds.payment
TYPES
User
Course
Paymentpackage-info.java
A package-info.java file can contain package-level documentation and package annotations.
/**
* Contains classes responsible
* for student management.
*/
package com.programinds.student;Real-World Package Example
com.programinds
├── authentication
│ ├── AuthController
│ ├── AuthService
│ └── LoginRequest
│
├── user
│ ├── User
│ ├── UserController
│ ├── UserService
│ └── UserRepository
│
├── course
│ ├── Course
│ ├── CourseController
│ ├── CourseService
│ └── CourseRepository
│
├── lesson
│ ├── Lesson
│ ├── LessonController
│ ├── LessonService
│ └── LessonRepository
│
└── common
├── exception
├── configuration
└── utilityE-Commerce Package Structure
com.example.store
├── product
│ ├── Product
│ ├── ProductService
│ └── ProductRepository
│
├── customer
│ ├── Customer
│ ├── CustomerService
│ └── CustomerRepository
│
├── cart
│ ├── Cart
│ └── CartService
│
├── order
│ ├── Order
│ ├── OrderService
│ └── OrderRepository
│
├── payment
│ ├── Payment
│ ├── PaymentService
│ └── PaymentGateway
│
└── common
├── exception
└── utilityCommon Package Errors
PACKAGE ERRORS
├── Missing Package Declaration
├── Wrong Package Declaration
├── Package Name Does Not Match Structure
├── Wrong Directory Structure
├── Incorrect Capitalization
├── Using Uppercase Package Names
├── Writing Package After Import
├── Writing Multiple Package Statements
├── Forgetting Semicolon
├── Running Packaged Class by Simple Name
├── Running from Wrong Directory
├── Wrong Classpath Root
├── Compiling from Wrong Location
├── Not Using -d Correctly
├── Missing Import
├── Wrong Import Path
├── Importing Wrong Class
├── Importing Nonexistent Package
├── Assuming Import Creates Object
├── Assuming Import Copies Code
├── Assuming java.util.* Imports Subpackages
├── Assuming Parent Package Imports Children
├── Assuming Child Package Has Parent Access
├── Confusing Package Hierarchy with Inheritance
├── Using Same Simple Class Name Without Resolving Conflict
├── Importing Both Conflicting Classes
├── Forgetting Fully Qualified Name
├── Accessing Package-Private Class from Another Package
├── Accessing Package-Private Member from Another Package
├── Accessing private Member from Same Package
├── Misunderstanding protected Access
├── Public Class Name Not Matching File Name
├── Multiple Public Top-Level Classes in One File
├── Using Default Package in Large Project
├── Trying to Import from Default Package
├── Poor Package Naming
├── Using Spaces in Package Names
├── Using Hyphens in Package Names
├── Using Meaningless Names
├── Creating Excessively Deep Package Structures
├── Creating One Package for Every Class
├── Putting Every Class in One Package
├── Mixing Unrelated Responsibilities
├── Creating Circular Package Dependencies
├── Overusing Utility Packages
├── Overusing Common Packages
├── Hiding Domain Structure
├── Excessive Static Imports
├── Static Import Name Conflicts
├── Wrong JAR Classpath
├── Missing Dependency JAR
├── Incorrect Classpath Separator
├── Package Missing from JAR
├── Wrong Main Class
├── Moving Class Without Updating Package
├── Moving Class Without Updating Imports
├── Renaming Package Manually and Missing References
└── Ignoring IDE Refactoring ToolsBest Practices
- Use named packages for professional Java projects.
- Avoid the default package.
- Use lowercase package names.
- Follow reverse domain naming for unique root packages.
- Use meaningful package names.
- Keep package names concise.
- Organize related classes together.
- Separate unrelated responsibilities.
- Choose a consistent package organization strategy.
- Use layer-based organization when it fits the application.
- Use feature-based organization when it improves domain cohesion.
- Do not create unnecessary package depth.
- Do not place every class in a separate package.
- Do not place the entire application in one package.
- Use public access only when external access is required.
- Use package-private access for internal package implementation details.
- Understand that subpackages are independent packages.
- Do not assume wildcard imports include subpackages.
- Prefer clear imports.
- Resolve class name conflicts explicitly.
- Use fully qualified names when necessary.
- Avoid unnecessary wildcard static imports.
- Use static imports only when they improve readability.
- Keep package declarations consistent with directory structure.
- Use IDE refactoring tools when moving classes.
- Do not manually move large groups of classes without updating references.
- Keep source roots separate from package directories.
- Understand the classpath root.
- Use build tools to manage dependencies and classpaths.
- Keep production and test source structures organized.
- Use src/main/java for standard Maven and Gradle production code.
- Use src/test/java for standard Maven and Gradle test code.
- Keep test package structures aligned with production code when appropriate.
- Avoid generic packages such as misc.
- Avoid turning common into a dumping ground.
- Avoid excessive utility classes.
- Keep domain-specific code near its domain.
- Use package-info.java when package-level documentation is valuable.
- Document package responsibilities in large applications.
- Avoid unnecessary circular dependencies between packages.
- Design package dependencies intentionally.
- Keep low-level packages independent from high-level presentation details when architecture requires it.
- Preserve package structure inside JAR files.
- Use clear root packages for libraries.
- Avoid exposing internal implementation packages unnecessarily.
- Test package visibility intentionally.
- Use package-private types when external access is not needed.
- Keep class names meaningful within their package context.
- Review imports after refactoring.
- Remove unused imports.
- Use automatic import organization carefully.
- Understand which package contains a class before importing it.
- Use Java API documentation to identify correct packages.
- Treat package structure as part of application architecture.
Common Misconceptions
- A package is not a class.
- A package is not an object.
- A package is not inheritance.
- A package is a namespace for organizing types.
- A package declaration does not import anything.
- An import statement does not create an object.
- An import statement does not copy code.
- An import statement mainly helps resolve type names.
- java.lang is automatically available.
- java.util is not automatically imported.
- Types in the same package do not need imports.
- A wildcard import does not recursively import subpackages.
- com.example and com.example.service are separate packages.
- A subpackage does not inherit access from its parent package.
- A parent package does not automatically access child package internals.
- Package names are case-sensitive.
- Package names normally use lowercase letters.
- Dots in package names correspond to directory levels.
- The package statement must come before imports.
- A source file can have only one package declaration.
- A public top-level class name must match its file name.
- Only one public top-level class can exist in one source file.
- Package-private means no access modifier is written.
- Package-private members are not accessible from subpackages.
- private members are not accessible merely because another class is in the same package.
- protected is not the same as public.
- The default package is not recommended for professional applications.
- Classes in named packages cannot import classes from the unnamed package.
- A fully qualified class name includes its package.
- Two packages can contain classes with the same simple name.
- Conflicting simple names may require fully qualified references.
- Static import imports static members, not ordinary instance members.
- Static import should not be overused.
- The classpath points to package roots, not individual package directories in normal usage.
- A JAR file can contain many packages.
- Packages and modules are not the same concept.
- A module can contain multiple packages.
- Package structure is an architectural decision, not only a folder arrangement.
Practice Exercises
- Create a package named com.programinds.app.
- Create a Main class inside it.
- Add the correct package declaration.
- Compile the class.
- Run it using its fully qualified class name.
- Create a com.programinds.model package.
- Create a Student class.
- Create a com.programinds.app package.
- Import Student into Main.
- Create a Student object.
- Display student information.
- Use java.util.ArrayList without an import statement.
- Write the complete fully qualified class name.
- Create the object.
- Add three values.
- Display the collection.
- Use java.util.Date.
- Use java.sql.Date in the same class.
- Import one Date class.
- Use the fully qualified name for the other.
- Explain why both simple names cannot be imported normally together.
- Create two classes in the same package.
- Create a package-private method in the first class.
- Call it from the second class.
- Move the second class to another package.
- Observe the access error.
- Create com.programinds.student.
- Create com.programinds.student.service.
- Create a class in each package.
- Test package-private access.
- Explain why the subpackage does not receive same-package access.
- Import Math.PI statically.
- Import Math.sqrt() statically.
- Calculate the area of a circle.
- Call sqrt() without writing Math.
- Explain whether the static imports improve readability.
- Create model, service, and app packages.
- Create Book and Member model classes.
- Create LibraryService.
- Create Main in the app package.
- Import and use the required classes.
- Create user, course, and payment packages.
- Add a model and service class to each feature.
- Create an application entry point.
- Import classes from all three features.
- Explain the organization.
- Create multiple packaged classes.
- Compile them into a classes directory.
- Create a JAR file.
- Inspect the package structure inside the JAR.
- Use the JAR from another Java program.
Common Interview Questions
What is a package in Java?
A package is a namespace used to group related Java types and organize application code.
Why are packages used?
Packages improve organization, prevent naming conflicts, support access control, and make large applications easier to maintain.
What are the two main types of packages?
Built-in packages provided by Java and user-defined packages created by developers.
Which package is automatically imported?
The java.lang package is automatically available.
Do classes in the same package require imports?
No. Types in the same package can normally be referenced by their simple names.
What is a fully qualified class name?
It is the complete package name followed by the class name, such as java.util.ArrayList.
What does the import statement do?
It allows a type or static member to be referenced without repeatedly writing its fully qualified name.
Does import load a class into memory?
No. An import is primarily a compile-time name-resolution convenience.
Does a wildcard import include subpackages?
No. It includes accessible types directly in the specified package, not types in subpackages.
What is the default access modifier?
When no modifier is written, the member or top-level type has package-private access.
Are parent packages and subpackages the same package?
No. They are independent packages.
What is static import?
Static import allows accessible static members to be referenced without qualifying them with the declaring class name.
What is the default package?
It is the unnamed package used by source files that contain no package declaration.
Why should the default package be avoided?
It provides poor organization, does not scale, and types in named packages cannot import types from the unnamed package.
What is the relationship between packages and directories?
Package name components normally correspond to directory levels under a source or classpath root.
Can two packages contain classes with the same name?
Yes. Their fully qualified names remain different.
What is package-private access?
It is access limited to classes in the same package and is created by omitting an access modifier.
What is the classpath?
The classpath tells Java tools where to search for compiled classes and other classpath resources.
Can a JAR contain multiple packages?
Yes. JAR files commonly contain many package hierarchies.
What is package-info.java?
It is a source file used for package-level documentation and package annotations.
Frequently Asked Questions
Can I create my own Java package?
Yes. User-defined packages are a standard way to organize application code.
Can a class belong to multiple packages?
No. A top-level type belongs to the single package declared for its source file.
Can one source file contain multiple package statements?
No. A source file can contain at most one package declaration.
Can I use a class without importing it?
Yes, if it is in the same package, in java.lang, or referenced using its fully qualified name.
Is java.util.* slower than individual imports?
Wildcard imports do not inherently make runtime execution slower. Import resolution is a compile-time concern.
Does import java.util.* import java.util.concurrent?
No. Subpackages are independent and must be imported separately.
Should package names use uppercase letters?
Java conventions normally use lowercase package names.
Can a package contain interfaces and enums?
Yes. Packages can contain classes, interfaces, enums, records, annotations, and other Java types.
Can a package contain another package?
Package names can appear hierarchical, but Java treats each named package as an independent namespace.
What should I learn after Packages?
The next lesson covers Encapsulation in Java.
Key Takeaways
- A package is a namespace for organizing related Java types.
- Packages improve code organization.
- Packages help prevent naming conflicts.
- Packages work with access control.
- Packages support modular application design.
- Java provides built-in packages.
- Developers can create user-defined packages.
- java.lang contains fundamental Java classes.
- java.lang is automatically available.
- java.util contains utility and collection classes.
- java.io contains traditional input and output classes.
- java.nio contains modern file and buffer APIs.
- java.time contains the modern date and time API.
- java.net contains networking APIs.
- java.sql contains core JDBC APIs.
- The package statement declares the package of a source file.
- The package statement appears before imports.
- A source file can have at most one package declaration.
- Package names are case-sensitive.
- Package names normally use lowercase letters.
- Package names commonly map to directory structures.
- Each dot represents another package name component.
- The javac -d option can create package output directories.
- Packaged classes are run using fully qualified class names.
- The classpath must contain the package root.
- A fully qualified name includes package and class names.
- Imports allow simple type names to be used.
- Imports do not create objects.
- Imports do not copy source code.
- Types in the same package do not need imports.
- Types in java.lang do not need imports.
- Single-type imports import one type name.
- Wildcard imports cover types directly in one package.
- Wildcard imports do not include subpackages.
- Two packages can contain classes with the same simple name.
- Fully qualified names resolve class name conflicts.
- Subpackages are independent packages.
- Parent packages do not automatically access child package internals.
- Child packages do not automatically access parent package internals.
- Reverse domain naming helps create unique package names.
- public members can be accessible across packages.
- Default access is package-private.
- Package-private members are accessible only in the same package.
- private members are accessible only inside their declaring class.
- protected access includes package access and inheritance-related access.
- A public top-level class name must match its file name.
- Only one public top-level class can exist in one source file.
- Additional top-level classes can be package-private.
- Static import imports accessible static members.
- Static imports should be used carefully.
- Packages can be organized by technical layer.
- Packages can be organized by business feature.
- Small and large applications may use different package strategies.
- IDEs can create and refactor packages.
- Maven commonly uses src/main/java and src/test/java.
- Gradle commonly uses the same Java source layout.
- The default package should be avoided in professional projects.
- Named packages provide scalable organization.
- The classpath tells Java where to find classes.
- JAR files preserve package structures.
- A JAR can contain multiple packages.
- Executable JAR files can define a main class.
- Packages and modules are different concepts.
- Modules can contain multiple packages.
- package-info.java can document a package.
- Package structure is part of application architecture.
- Good package design improves readability and maintainability.
- Understanding packages is essential for Java libraries, frameworks, Maven, Gradle, Spring, JDBC, testing, and enterprise development.
Summary
A package is a Java namespace used to group related classes, interfaces, enums, records, annotations, and other types. Packages provide structure to applications and help developers organize source code according to responsibilities, features, layers, or business domains.
Java provides many built-in packages such as java.lang, java.util, java.io, java.nio, java.time, java.net, and java.sql. Developers can also create user-defined packages for application-specific code.
The package declaration identifies the package to which a source file belongs. Package names normally correspond to directory structures, and professional applications commonly use lowercase reverse-domain naming such as com.programinds.student.
Classes from other packages can be used through fully qualified names or import statements. Imports improve readability by allowing simple class names to be used, but they do not create objects, copy source code, or recursively import subpackages.
Packages are closely connected to Java access control. Package-private types and members are accessible only within the same package, while public types and members can be exposed more broadly. Parent packages and subpackages remain independent for access purposes.
Static imports provide direct access to static members, while the classpath tells Java tools where package roots and compiled classes can be found. Compiled packages can also be distributed inside JAR files.
Real-world applications use package structures to separate models, services, repositories, controllers, exceptions, configuration, utilities, and business features. Good package design is therefore an important part of Java application architecture.
- You understand what a package is.
- You understand why packages are important.
- You understand package structure.
- You know the two main types of packages.
- You understand built-in packages.
- You know common Java packages.
- You understand java.lang.
- You understand java.util.
- You understand java.io.
- You understand java.nio.
- You understand java.time.
- You understand java.net.
- You understand java.sql.
- You understand user-defined packages.
- You can create a package.
- You can write a package declaration.
- You understand package statement rules.
- You understand package directory structures.
- You understand packaged class compilation.
- You understand how to run packaged classes.
- You understand the javac -d option.
- You can use classes from other packages.
- You understand fully qualified class names.
- You understand the import statement.
- You can import a single class.
- You understand wildcard imports.
- You know the difference between single and wildcard imports.
- You understand automatic imports.
- You understand import rules.
- You can resolve import name conflicts.
- You understand same-package access.
- You understand subpackages.
- You understand that packages are independent.
- You can create subpackages.
- You understand package naming conventions.
- You understand reverse domain naming.
- You understand access control across packages.
- You understand public access.
- You understand default access.
- You understand protected access.
- You understand private access.
- You understand package-private access.
- You understand public class rules.
- You understand source file naming rules.
- You understand multiple classes in one source file.
- You understand static imports.
- You can import static members.
- You understand wildcard static imports.
- You know when static imports should be used.
- You understand package organization.
- You understand layer-based packages.
- You understand feature-based packages.
- You know the difference between layer-based and feature-based structures.
- You understand small project package structures.
- You understand large project package structures.
- You understand how IDEs manage packages.
- You understand packages in Maven projects.
- You understand packages in Gradle projects.
- You understand the default package.
- You know why the default package should be avoided.
- You understand packages and the classpath.
- You understand what the classpath is.
- You understand classpath configuration.
- You understand packages inside JAR files.
- You understand how JAR files are created.
- You understand how classes from JAR files are used.
- You understand executable JAR files.
- You understand the relationship between packages and modules.
- You understand package-info.java.
- You understand real-world package structures.
- You can identify common package errors.
- You know package best practices.
- You are ready to learn Encapsulation in Java.