LearnContact
Lesson 2055 min read

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 Example
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 You Will Learn
  • 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.

Package Concept
APPLICATION

├── com.programinds.student
│
│   ├── Student
│   ├── StudentService
│   └── StudentRepository
│
├── com.programinds.course
│
│   ├── Course
│   ├── CourseService
│   └── CourseRepository
│
└── com.programinds.payment

    ├── Payment
    ├── PaymentService
    └── PaymentGateway

Instead 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 Analogy
COMPANY

├── HUMAN RESOURCES
│
│   ├── Recruiter
│   ├── HRManager
│   └── PayrollOfficer
│
├── FINANCE
│
│   ├── Accountant
│   ├── Auditor
│   └── FinanceManager
│
└── TECHNOLOGY

    ├── Developer
    ├── Tester
    └── SystemAdministrator


JAVA APPLICATION

├── hr package
├── finance package
└── technology package

The company remains one organization, but departments make responsibilities clearer. Java packages provide the same kind of organization for source code.

Package Structure

Package Hierarchy
com.programinds

        │
        ├── user
        │     │
        │     ├── User
        │     └── UserService
        │
        ├── course
        │     │
        │     ├── Course
        │     └── CourseService
        │
        └── payment
              │
              ├── Payment
              └── PaymentService

A package name commonly contains multiple parts separated by dots. Each part usually corresponds to a directory in the source structure.

Types of Packages

Package Types
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.payment

Built-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.

Using Built-in Packages
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

Important 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 APIs

The java.lang Package

The java.lang package contains fundamental classes required by almost every Java program. Java imports this package automatically.

java.lang Classes
String message = "Hello";

Integer number = 100;

Double price = 99.99;

System.out.println(message);


Math.sqrt(25);


Thread thread;
Common java.lang Types
String

Object

System

Math

Integer

Double

Boolean

Character

StringBuilder

StringBuffer

Thread

Exception

RuntimeException
Automatic Import
  • 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.

java.util Example
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);

    }

}
Common java.util Types
Scanner

ArrayList

LinkedList

HashSet

HashMap

Collections

Arrays

Optional

Random

UUID

The java.io Package

The java.io package provides traditional input and output classes for files, streams, readers, writers, and serialization.

java.io Example
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.

java.nio Example
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.

java.time Example
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.

java.net Example
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.

Common java.sql Types
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.

Example Application Packages
com.programinds

├── model
├── service
├── repository
├── controller
├── exception
├── configuration
└── utility

Creating a Package

Student.java
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 Syntax
package packageName;
Examples
package student;


package com.programinds;


package com.programinds.course;


package com.programinds.payment.service;

Package Statement Rules

Important 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.
Correct Order
package com.programinds.student;


import java.util.ArrayList;


public class Student {

}
Source File Order
1. PACKAGE DECLARATION

2. IMPORT STATEMENTS

3. TYPE DECLARATIONS

Package and Directory Structure

Package names normally correspond to directories. Each dot in the package name represents another directory level.

Package Declaration
package com.programinds.student;
Matching Directory
src

└── com
    └── programinds
        └── student
            └── Student.java
Mapping
PACKAGE

com.programinds.student


DIRECTORIES

com
 │
 └── programinds
       │
       └── student

Compiling Packaged Classes

Student.java
package com.programinds.student;


public class Student {

    public static void main(
        String[] args
    ) {

        System.out.println(
            "Student class"
        );

    }

}
Compile
javac Student.java

For manual compilation, the class file must ultimately be placed in a directory structure matching the declared package.

Running Packaged Classes

Run Using Fully Qualified Name
java com.programinds.student.Student
Important
  • 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.

Compile with -d
javac -d . Student.java
Generated Structure
.

└── com
    └── programinds
        └── student
            └── Student.class

Using Classes from Another Package

Student.java
package com.programinds.model;


public class Student {

    public void display() {

        System.out.println(
            "Student"
        );

    }

}
Main.java
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.

Fully Qualified Names
java.lang.String

java.util.Scanner

java.util.ArrayList

java.time.LocalDate

com.programinds.model.Student
Without Import
public 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.

Without Import
java.util.Scanner scanner =
        new java.util.Scanner(
            System.in
        );
With Import
import java.util.Scanner;


Scanner scanner =
        new Scanner(System.in);
What import Does
  • 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

Single-Type Import
import java.util.Scanner;


public class Main {

    public static void main(
        String[] args
    ) {

        Scanner scanner =
                new Scanner(System.in);

    }

}

Wildcard Imports

Wildcard Import
import java.util.*;

The wildcard allows types directly inside the specified package to be referenced without individual imports.

Using Multiple java.util Types
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

Comparison
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 types

Automatic Imports

Java automatically makes certain types available without explicit import statements.

Automatically Available
1. TYPES IN THE SAME PACKAGE


2. TYPES IN java.lang


EXAMPLES

String

System

Math

Object

Integer

Double

Import 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.

Same Simple Name
java.util.Date


java.sql.Date
Resolve Conflict
import 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.

Student.java
package com.programinds.student;


public class Student {

}
StudentService.java
package com.programinds.student;


public class StudentService {

    Student student =
            new Student();

}

Subpackages

A package name can contain multiple hierarchical-looking levels separated by dots.

Package Names
com.programinds


com.programinds.student


com.programinds.student.service


com.programinds.student.repository

Packages 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.

Independent Packages
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
Important
  • 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

StudentService.java
package com.programinds.student.service;


public class StudentService {

}
Directory Structure
src

└── com
    └── programinds
        └── student
            │
            ├── Student.java
            │
            ├── service
            │   └── StudentService.java
            │
            └── repository
                └── StudentRepository.java

Package 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 and Poor Names
GOOD

com.programinds.student

com.programinds.course

com.programinds.payment


POOR

StudentPackage

my-package

randomStuff

ABC

everything

Reverse Domain Naming

Organizations commonly reverse their internet domain name when creating the root Java package. This helps reduce package name collisions.

Reverse Domain Examples
DOMAIN

programinds.com


PACKAGE ROOT

com.programinds



DOMAIN

example.org


PACKAGE ROOT

org.example



DOMAIN

company.co.in


PACKAGE ROOT

in.co.company

Package Naming Examples

Application Packages
com.programinds.user

com.programinds.course

com.programinds.payment

com.programinds.authentication

com.programinds.notification

com.programinds.common

com.programinds.configuration

Access Control and Packages

Packages work closely with Java access modifiers. Accessibility depends on both the modifier and the location of the accessing code.

Access Modifiers
public


protected


default
No modifier


private

public Access

A public class or member can be accessed from other packages when the containing type is also accessible.

Public Class
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-Private Class
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.

Protected Member
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.

Private Member
package com.programinds.model;


public class Student {

    private int marks;

}

Access Modifier Table

Accessibility
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 rules

Package-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-Private Method
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.

Public Class
package com.programinds.course;


public class Course {

}

Class File Naming Rules

Source File 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

Student.java
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.

Without Static Import
double result =
        Math.sqrt(25);


System.out.println(
        Math.PI
);
With Static Import
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

Static Import Syntax
import static packageName.ClassName.memberName;
Example
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 All Accessible Static Members
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

Use Carefully
  • 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.

Common Responsibilities
model

Domain objects


service

Business logic


repository

Data access


controller

Request handling


exception

Custom exceptions


configuration

Application configuration


utility

Shared helper code

Layer-Based Package Structure

Layer-Based Structure
com.programinds

├── controller
│   ├── UserController
│   └── CourseController
│
├── service
│   ├── UserService
│   └── CourseService
│
├── repository
│   ├── UserRepository
│   └── CourseRepository
│
└── model
    ├── User
    └── Course

In a layer-based structure, classes are grouped according to their technical responsibility.

Feature-Based Package Structure

Feature-Based Structure
com.programinds

├── user
│   ├── User
│   ├── UserController
│   ├── UserService
│   └── UserRepository
│
└── course
    ├── Course
    ├── CourseController
    ├── CourseService
    └── CourseRepository

In a feature-based structure, code belonging to one business feature is grouped together.

Layer-Based vs Feature-Based Packages

Comparison
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 requirements

Small Project Structure

Small Application
com.programinds.library

├── model
│   ├── Book
│   └── Member
│
├── service
│   └── LibraryService
│
└── app
    └── Main

Large Project Structure

Large Application
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
    └── utility

Packages 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.

Typical IDE Source View
src

└── com.programinds
    │
    ├── model
    │   └── Student
    │
    ├── service
    │   └── StudentService
    │
    └── app
        └── Main
IDE Note
  • 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

Maven Structure
project

└── src
    │
    ├── main
    │   └── java
    │       └── com
    │           └── programinds
    │               ├── model
    │               ├── service
    │               └── app
    │
    └── test
        └── java
            └── com
                └── programinds

In 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.

Gradle Java Structure
src

├── main
│   ├── java
│   │   └── com
│   │       └── programinds
│   │
│   └── resources
│
└── test
    ├── java
    │   └── com
    │       └── programinds
    │
    └── resources

The Default Package

A Java class without a package declaration belongs to the unnamed package, commonly called the default package.

Default Package Class
public class Main {

    public static void main(
        String[] args
    ) {

        System.out.println(
            "No package declaration"
        );

    }

}

Why Avoid the Default Package?

Professional Projects Should Use Named Packages
  • 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 Concept
CLASSPATH ROOT

.


PACKAGE

com.programinds.student


JVM LOOKS FOR

./com/programinds/student/Student.class

What is Classpath?

The classpath is a list of locations where Java tools search for compiled classes and other classpath resources.

Classpath Locations
CLASSPATH CAN INCLUDE

Directories

JAR files

Multiple locations

Setting the Classpath

Compile with Classpath
javac -cp classes Main.java
Run with Classpath
java -cp classes com.programinds.Main
Common Options
-cp


AND


-classpath


MEAN THE SAME THING

Packages and JAR Files

A JAR file is an archive that can contain compiled Java packages, classes, resources, and metadata.

JAR Contents
application.jar

├── META-INF
│   └── MANIFEST.MF
│
└── com
    └── programinds
        ├── model
        │   └── Student.class
        │
        └── service
            └── StudentService.class

Creating a JAR File

Create JAR
jar --create --file application.jar -C classes .

The package directory structure is preserved inside the JAR file.

Using Classes from a JAR File

Compile with JAR
javac -cp library.jar Main.java
Run with JAR
java -cp library.jar;. Main
Platform Note
  • 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.

Run Executable JAR
java -jar application.jar

Packages and Modules

Packages organize related Java types. Java modules operate at a higher level and group packages while defining dependencies and exported packages.

Relationship
MODULE

└── PACKAGES

    └── TYPES


EXAMPLE


MODULE

com.programinds.app


PACKAGES

com.programinds.user

com.programinds.course

com.programinds.payment


TYPES

User

Course

Payment

package-info.java

A package-info.java file can contain package-level documentation and package annotations.

package-info.java
/**
 * Contains classes responsible
 * for student management.
 */
package com.programinds.student;

Real-World Package Example

Learning Platform
com.programinds

├── authentication
│   ├── AuthController
│   ├── AuthService
│   └── LoginRequest
│
├── user
│   ├── User
│   ├── UserController
│   ├── UserService
│   └── UserRepository
│
├── course
│   ├── Course
│   ├── CourseController
│   ├── CourseService
│   └── CourseRepository
│
├── lesson
│   ├── Lesson
│   ├── LessonController
│   ├── LessonService
│   └── LessonRepository
│
└── common
    ├── exception
    ├── configuration
    └── utility

E-Commerce Package Structure

E-Commerce Application
com.example.store

├── product
│   ├── Product
│   ├── ProductService
│   └── ProductRepository
│
├── customer
│   ├── Customer
│   ├── CustomerService
│   └── CustomerRepository
│
├── cart
│   ├── Cart
│   └── CartService
│
├── order
│   ├── Order
│   ├── OrderService
│   └── OrderRepository
│
├── payment
│   ├── Payment
│   ├── PaymentService
│   └── PaymentGateway
│
└── common
    ├── exception
    └── utility

Common Package Errors

Common 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 Tools

Best 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

Avoid These 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

Exercise 1: Create Your First Package
  • 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.
Exercise 2: Model and Application Packages
  • 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.
Exercise 3: Fully Qualified Names
  • Use java.util.ArrayList without an import statement.
  • Write the complete fully qualified class name.
  • Create the object.
  • Add three values.
  • Display the collection.
Exercise 4: Import Conflict
  • 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.
Exercise 5: Package-Private Access
  • 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.
Exercise 6: Subpackages
  • 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.
Exercise 7: Static Import
  • 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.
Exercise 8: Library Application Structure
  • 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.
Exercise 9: Feature-Based Structure
  • 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.
Exercise 10: Build a JAR
  • 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.

Lesson 20 Completed
  • 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.
Next Lesson →

Encapsulation in Java