Packages in Java
Packages in Java
Every Java program you write lives inside a package — even if you never declare one. When you start writing enterprise-grade code with dozens of classes, or when two developers on the same team both create a class called Order, packages are what prevent the collision and keep everything organised.
A package in Java is a namespace that groups related classes, interfaces, and sub-packages together. The analogy is a folder on your computer — just as you put all your music files in a Music folder and all your documents in a Documents folder, Java puts related classes into packages. java.util holds utility classes. java.io holds input/output classes. Your own com.flipkart.order package holds all order-related classes for a Flipkart-like application.
Why Packages Exist — Three Reasons
Reason 1 — Namespace collision prevention:
Without packages:
Developer A writes: class Order { ... } ← conflict!
Developer B writes: class Order { ... } ← same name, same scope
With packages:
com.flipkart.order.Order ← fully qualified: no conflict
com.amazon.cart.Order ← completely separate
Reason 2 — Access control:
Classes in the same package can access each other's
package-private (default) members.
Classes outside the package cannot.
Reason 3 — Organisation and navigation:
com.myapp
├── model → Order, User, Product (data classes)
├── service → OrderService, PaymentService (logic)
├── repository → OrderRepository (database access)
├── controller → OrderController (API endpoints)
└── util → DateUtil, StringUtil (helpers)
Built-In Java Packages
Java ships with hundreds of packages. These are the ones every Java developer uses:
1// File: BuiltInPackagesDemo.java
2
3import java.util.ArrayList;
4import java.util.Arrays;
5import java.util.Collections;
6import java.util.HashMap;
7import java.util.List;
8import java.util.Map;
9import java.util.Optional;
10import java.io.File;
11import java.math.BigDecimal;
12import java.time.LocalDate;
13
14public class BuiltInPackagesDemo {
15
16 public static void main(String[] args) {
17
18 // java.util — utility classes: collections, date, random
19 List<String> cities = new ArrayList<>(Arrays.asList("Mumbai", "Delhi", "Bengaluru"));
20 Collections.sort(cities);
21 System.out.println("java.util.List : " + cities);
22
23 Map<String, Integer> scores = new HashMap<>();
24 scores.put("Priya", 95);
25 scores.put("Rohan", 88);
26 System.out.println("java.util.Map : " + scores);
27
28 Optional<String> opt = Optional.of("Hello");
29 System.out.println("java.util.Optional: " + opt.get());
30
31 // java.io — file and stream operations
32 File file = new File("example.txt");
33 System.out.println("java.io.File : exists=" + file.exists());
34
35 // java.math — precise arithmetic (for money calculations)
36 BigDecimal price = new BigDecimal("1299.99");
37 BigDecimal tax = new BigDecimal("0.18");
38 BigDecimal total = price.add(price.multiply(tax));
39 System.out.println("java.math.BigDecimal: Rs." + total);
40
41 // java.time — modern date/time API (Java 8+)
42 LocalDate today = LocalDate.now();
43 System.out.println("java.time.LocalDate: " + today);
44 }
45}Output:
java.util.List : [Bengaluru, Delhi, Mumbai]
java.util.Map : {Priya=95, Rohan=88}
java.util.Optional: Hello
java.io.File : exists=false
java.math.BigDecimal: Rs.1533.9882
java.time.LocalDate: 2024-01-15
Key Built-In Package Reference
| Package | Purpose | Key Classes |
|---|---|---|
java.lang | Core language — auto-imported always | String, Integer, Math, System, Object, Thread |
java.util | Utility: collections, date, random | ArrayList, HashMap, Arrays, Collections, Scanner |
java.io | File and stream I/O | File, FileReader, BufferedReader, PrintWriter |
java.nio | Non-blocking I/O (modern file ops) | Path, Files, Paths, Channels |
java.math | Precise arithmetic | BigDecimal, BigInteger |
java.time | Date and time (Java 8+) | LocalDate, LocalDateTime, ZonedDateTime |
java.net | Networking | URL, HttpURLConnection, Socket |
java.util.stream | Functional streams (Java 8+) | Stream, Collectors, Optional |
java.util.concurrent | Thread safety and parallelism | ExecutorService, ConcurrentHashMap, Future |
java.sql | Database connectivity (JDBC) | Connection, PreparedStatement, ResultSet |
java.lang is the only package that is automatically imported in every Java file — no import statement needed. That is why you can write String, System.out.println, and Math.max without any import.
Declaring a Package
A package declaration is the first statement in a Java file (before any import or class declaration). It uses the package keyword followed by the package name.
1// File: Order.java
2// This file must be saved in: src/com/flipkart/order/Order.java
3
4package com.flipkart.order; // ← must be line 1 (before imports)
5
6import java.time.LocalDate; // ← imports come after package declaration
7
8public class Order {
9
10 private final String orderId;
11 private final String customerId;
12 private final double amount;
13 private final LocalDate orderDate;
14
15 public Order(String orderId, String customerId, double amount) {
16 this.orderId = orderId;
17 this.customerId = customerId;
18 this.amount = amount;
19 this.orderDate = LocalDate.now();
20 }
21
22 public String getOrderId() { return orderId; }
23 public String getCustomerId() { return customerId; }
24 public double getAmount() { return amount; }
25 public LocalDate getOrderDate(){ return orderDate; }
26
27 @Override
28 public String toString() {
29 return "Order{id=" + orderId + ", customer=" + customerId
30 + ", amount=Rs." + amount + ", date=" + orderDate + "}";
31 }
32}1// File: OrderService.java
2// Save in: src/com/flipkart/service/OrderService.java
3
4package com.flipkart.service; // different package from Order
5
6import com.flipkart.order.Order; // must import — different package
7
8public class OrderService {
9
10 public Order createOrder(String customerId, double amount) {
11 String orderId = "ORD-" + System.currentTimeMillis();
12 Order order = new Order(orderId, customerId, amount);
13 System.out.println("Created: " + order);
14 return order;
15 }
16
17 public void processOrder(Order order) {
18 System.out.println("Processing order: " + order.getOrderId()
19 + " for Rs." + order.getAmount());
20 }
21}1// File: Main.java
2// Save in: src/Main.java (default package — no package declaration)
3
4import com.flipkart.order.Order;
5import com.flipkart.service.OrderService;
6
7public class Main {
8
9 public static void main(String[] args) {
10 OrderService service = new OrderService();
11 Order order = service.createOrder("CUST-501", 1299.50);
12 service.processOrder(order);
13 }
14}Output:
Created: Order{id=ORD-1705312200000, customer=CUST-501, amount=Rs.1299.5, date=2024-01-15}
Processing order: ORD-1705312200000 for Rs.1299.5
Package Naming Conventions
Java package names follow a strict convention to guarantee global uniqueness and reflect the project structure.
Convention: reverse domain name + project + layer + module Examples: Company / Domain → Reversed Domain ───────────────────────────────────────────── flipkart.com → com.flipkart meesho.com → com.meesho razorpay.com → com.razorpay dev.stackflow (personal) → com.devstackflow Full package names: com.flipkart.order.model → Order, Cart, Product (data) com.flipkart.order.service → OrderService, CartService (logic) com.flipkart.order.repository → OrderRepository (DB access) com.flipkart.order.controller → OrderController (HTTP API) com.flipkart.order.exception → OrderNotFoundException, PaymentException com.flipkart.order.util → OrderIdGenerator, AmountFormatter Rules: — All lowercase (no CamelCase, no underscores recommended) — No Java keywords (e.g., not com.flipkart.class) — Reverse domain name as prefix for global uniqueness — Layer name (model, service, util) as last segment
Package and Folder Structure
The package name maps directly to the folder structure on disk. package com.meesho.catalog.service means the file lives in com/meesho/catalog/service/ directory.
Folder structure for a Meesho-like application:
src/
└── main/
└── java/
└── com/
└── meesho/
└── catalog/
├── model/
│ ├── Product.java → package com.meesho.catalog.model
│ ├── Category.java → package com.meesho.catalog.model
│ └── Seller.java → package com.meesho.catalog.model
├── service/
│ ├── ProductService.java → package com.meesho.catalog.service
│ └── CategoryService.java → package com.meesho.catalog.service
├── repository/
│ └── ProductRepository.java→ package com.meesho.catalog.repository
├── controller/
│ └── ProductController.java→ package com.meesho.catalog.controller
├── exception/
│ └── ProductNotFoundException.java
└── util/
└── SlugGenerator.java → package com.meesho.catalog.util
Every Java file in com/meesho/catalog/model/ must start with package com.meesho.catalog.model; — the compiler enforces that the package declaration matches the file's location.
Sub-packages
Sub-packages are simply packages nested inside other packages through deeper folder hierarchies. Java treats each package independently — com.meesho.catalog and com.meesho.catalog.model are two completely separate packages with no parent-child access relationship.
1// File: SubPackageDemo.java
2
3package com.devstackflow.demo;
4
5// java.util is a package — java.util.stream is a SUB-package
6// They are independent — importing java.util does NOT import java.util.stream
7import java.util.List;
8import java.util.ArrayList;
9import java.util.stream.Collectors; // must import separately
10
11public class SubPackageDemo {
12
13 public static void main(String[] args) {
14
15 List<String> names = new ArrayList<>(List.of(
16 "Priya", "Rohan", "Sneha", "Karan", "Ananya"));
17
18 // java.util.stream.Collectors — sub-package of java.util
19 String joined = names.stream()
20 .filter(n -> n.length() > 4)
21 .collect(Collectors.joining(", "));
22
23 System.out.println("Long names: " + joined);
24
25 // Important: sub-package classes are NOT visible from parent package
26 // Importing 'java.util.*' does NOT import java.util.stream.Stream
27 // Every package must be explicitly imported
28 }
29}Output:
Long names: Priya, Rohan, Sneha, Karan, Ananya
Default Package — The Package You Should Avoid
A class with no package declaration lives in the default package — an unnamed package. The compiler allows it, but production code should never use it.
1// File: DefaultPackageClass.java
2// No package declaration — this is in the DEFAULT PACKAGE
3
4public class DefaultPackageClass {
5 public static void greet() {
6 System.out.println("I am in the default package.");
7 }
8}Problems with the default package:
1. Cannot be imported by classes in named packages
import DefaultPackageClass; ← compile error from named package
2. No namespace — collision risk with any other default-package class
3. IDEs and build tools (Maven, Gradle) warn about it
4. Spring Boot, JPA, and other frameworks do not scan the default package
Verdict: Only acceptable for quick throwaway demos.
All production code must declare a package.
Real-World Example — Multi-Package E-Commerce Application
The Business Problem
A backend service for a simplified e-commerce platform like Myntra structures its code into clear packages: model for data, service for business logic, util for helpers, and exception for custom errors. This mirrors how real-world Java projects are organised.
1// File: com/myntra/store/model/Product.java
2package com.myntra.store.model;
3
4public class Product {
5 private final String productId;
6 private final String name;
7 private final String category;
8 private double price;
9 private int stockCount;
10
11 public Product(String productId, String name,
12 String category, double price, int stockCount) {
13 this.productId = productId;
14 this.name = name;
15 this.category = category;
16 this.price = price;
17 this.stockCount = stockCount;
18 }
19
20 public String getProductId() { return productId; }
21 public String getName() { return name; }
22 public String getCategory() { return category; }
23 public double getPrice() { return price; }
24 public int getStockCount() { return stockCount; }
25 public void setPrice(double price) { this.price = price; }
26 public void setStockCount(int count) { this.stockCount = count; }
27
28 @Override
29 public String toString() {
30 return String.format("[%s] %-25s Rs.%7.2f | Stock: %d",
31 productId, name, price, stockCount);
32 }
33}1// File: com/myntra/store/exception/ProductNotFoundException.java
2package com.myntra.store.exception;
3
4public class ProductNotFoundException extends RuntimeException {
5 public ProductNotFoundException(String productId) {
6 super("Product not found: " + productId);
7 }
8}1// File: com/myntra/store/util/PriceFormatter.java
2package com.myntra.store.util;
3
4import java.text.NumberFormat;
5import java.util.Locale;
6
7public class PriceFormatter {
8
9 private static final NumberFormat FORMATTER =
10 NumberFormat.getCurrencyInstance(new Locale("en", "IN"));
11
12 public static String format(double amount) {
13 return FORMATTER.format(amount);
14 }
15
16 public static double applyDiscount(double price, double discountPercent) {
17 return price - (price * discountPercent / 100.0);
18 }
19}1// File: com/myntra/store/service/ProductService.java
2package com.myntra.store.service;
3
4import com.myntra.store.exception.ProductNotFoundException;
5import com.myntra.store.model.Product;
6import com.myntra.store.util.PriceFormatter;
7
8import java.util.ArrayList;
9import java.util.List;
10import java.util.Optional;
11import java.util.stream.Collectors;
12
13public class ProductService {
14
15 private final List<Product> catalogue = new ArrayList<>();
16
17 public void addProduct(Product product) {
18 catalogue.add(product);
19 }
20
21 public Product findById(String productId) {
22 return catalogue.stream()
23 .filter(p -> p.getProductId().equals(productId))
24 .findFirst()
25 .orElseThrow(() -> new ProductNotFoundException(productId));
26 }
27
28 public List<Product> findByCategory(String category) {
29 return catalogue.stream()
30 .filter(p -> p.getCategory().equalsIgnoreCase(category))
31 .collect(Collectors.toList());
32 }
33
34 public void applySeasonalDiscount(String category, double discountPercent) {
35 catalogue.stream()
36 .filter(p -> p.getCategory().equalsIgnoreCase(category))
37 .forEach(p -> {
38 double discounted = PriceFormatter.applyDiscount(
39 p.getPrice(), discountPercent);
40 p.setPrice(discounted);
41 });
42 }
43
44 public void printCatalogue() {
45 System.out.println("─".repeat(60));
46 System.out.printf("%-40s %10s %8s%n", "Product", "Price", "Stock");
47 System.out.println("─".repeat(60));
48 catalogue.forEach(p ->
49 System.out.printf("%-40s %10s %8d%n",
50 p.getName(),
51 PriceFormatter.format(p.getPrice()),
52 p.getStockCount()));
53 System.out.println("─".repeat(60));
54 }
55}1// File: com/myntra/store/StoreApp.java
2package com.myntra.store;
3
4import com.myntra.store.model.Product;
5import com.myntra.store.service.ProductService;
6import com.myntra.store.exception.ProductNotFoundException;
7
8public class StoreApp {
9
10 public static void main(String[] args) {
11
12 ProductService service = new ProductService();
13
14 service.addProduct(new Product("P001", "Floral Kurta", "Women Ethnic", 899.0, 150));
15 service.addProduct(new Product("P002", "Denim Jacket", "Men Casual", 1999.0, 80));
16 service.addProduct(new Product("P003", "Cotton Saree", "Women Ethnic", 1299.0, 60));
17 service.addProduct(new Product("P004", "Polo T-Shirt", "Men Casual", 599.0, 200));
18 service.addProduct(new Product("P005", "Embroidered Dupatta", "Women Ethnic", 499.0, 300));
19
20 System.out.println("╔══════════════════════════════════════════╗");
21 System.out.println("║ MYNTRA PRODUCT CATALOGUE ║");
22 System.out.println("╚══════════════════════════════════════════╝\n");
23
24 System.out.println("=== Full Catalogue ===");
25 service.printCatalogue();
26
27 System.out.println("\n=== Women Ethnic Category ===");
28 service.findByCategory("Women Ethnic")
29 .forEach(p -> System.out.println(" " + p));
30
31 System.out.println("\n=== Applying 20% Discount on Women Ethnic ===");
32 service.applySeasonalDiscount("Women Ethnic", 20.0);
33 service.findByCategory("Women Ethnic")
34 .forEach(p -> System.out.println(" " + p));
35
36 System.out.println("\n=== Find by ID ===");
37 try {
38 Product found = service.findById("P002");
39 System.out.println("Found : " + found);
40
41 service.findById("P999"); // does not exist
42 } catch (ProductNotFoundException ex) {
43 System.out.println("Error : " + ex.getMessage());
44 }
45 }
46}Output:
╔══════════════════════════════════════════╗
║ MYNTRA PRODUCT CATALOGUE ║
╚══════════════════════════════════════════╝
=== Full Catalogue ===
────────────────────────────────────────────────────────────
Product Price Stock
────────────────────────────────────────────────────────────
Floral Kurta ₹899.00 150
Denim Jacket ₹1,999.00 80
Cotton Saree ₹1,299.00 60
Polo T-Shirt ₹599.00 200
Embroidered Dupatta ₹499.00 300
────────────────────────────────────────────────────────────
=== Women Ethnic Category ===
[P001] Floral Kurta Rs. 899.00 | Stock: 150
[P003] Cotton Saree Rs.1299.00 | Stock: 60
[P005] Embroidered Dupatta Rs. 499.00 | Stock: 300
=== Applying 20% Discount on Women Ethnic ===
[P001] Floral Kurta Rs. 719.20 | Stock: 150
[P003] Cotton Saree Rs.1039.20 | Stock: 60
[P005] Embroidered Dupatta Rs. 399.20 | Stock: 300
=== Find by ID ===
Found : [P002] Denim Jacket Rs.1999.00 | Stock: 80
Error : Product not found: P999
Four packages, four concerns, clean separation. StoreApp can use Product and ProductService from different packages by importing them. ProductService uses PriceFormatter from util and throws ProductNotFoundException from exception. The folder structure maps exactly to these package names.
Best Practices
Always declare a package — never leave classes in the default package. Framework tools like Spring, Hibernate, and Lombok require named packages to scan for annotations. The default package cannot be imported by any named-package class, making its classes inaccessible to most of the application.
Follow the reverse-domain naming convention. com.yourcompany.projectname.layer is the universal standard. It prevents collisions across projects, libraries, and organisations. All lowercase — no numbers at the start, no Java keywords.
Match the package name to the folder structure exactly. The compiler requires it. If the file says package com.meesho.service but lives in com/meesho/model/, the compiler reports an error. In Maven and Gradle projects, src/main/java is the source root — everything below maps to the package name.
Group by layer, not by feature — until the project grows large enough. model, service, repository, controller, util, exception is the standard layered structure for small to mid-sized projects. Feature-based packaging (com.app.order, com.app.payment) becomes more natural in large microservice-style monorepos where each feature is nearly its own module.
Common Mistakes
Mistake 1 — Package Declaration Not on Line 1
1// WRONG — comments are fine, but no code or blank logic before package
2import java.util.List; // compile error — import before package declaration
3
4package com.myapp.service; // must be the FIRST non-comment statement
5
6// CORRECT order:
7package com.myapp.service; // 1. package (line 1)
8import java.util.List; // 2. imports
9public class Service { } // 3. classMistake 2 — Wrong Folder Location
1// File says:
2package com.myapp.service;
3
4// But file is saved at: src/com/myapp/model/Service.java
5// Compiler: "class Service is public, should be declared in Service.java"
6// (and cannot find it in the correct package location)
7
8// Fix: move the file to src/com/myapp/service/Service.javaMistake 3 — Assuming Sub-packages Share Visibility
1package com.myapp.util;
2
3class Helper { // package-private — visible only within com.myapp.util
4 static void doSomething() { }
5}
6
7// In com.myapp.util.io (a SUB-package):
8package com.myapp.util.io;
9import com.myapp.util.Helper; // compile error — Helper is package-private
10// Sub-packages have NO special access to parent package membersMistake 4 — Using Single-Segment Package Names
1// Too generic — risk of collision with other libraries
2package order; // BAD
3package service; // BAD
4package util; // BAD
5
6// Correct — reverse domain prefix guarantees uniqueness
7package com.myntra.order; // GOOD
8package com.myntra.service; // GOODInterview Questions
Q1. What is a package in Java and why is it used?
A package is a namespace that groups related classes, interfaces, and sub-packages together. It serves three purposes: preventing naming conflicts between classes from different developers or libraries that happen to share the same class name; providing a layer of access control through package-private visibility; and organising code into logical layers and modules that reflect the application's architecture. The package name maps directly to the folder structure on disk — com.flipkart.order means the class lives at com/flipkart/order/ClassName.java.
Q2. What is the default package in Java and why should you avoid it?
The default package is the unnamed package that a class belongs to when no package declaration is present. Classes in the default package cannot be imported by classes in any named package — the import keyword requires a fully qualified name with at least one dot, which the default package cannot provide. Additionally, frameworks like Spring and Hibernate cannot scan the default package for annotations, making the class invisible to dependency injection. The default package is acceptable only for throwaway test programs — all production code must declare a named package.
Q3. What is the difference between a package and a sub-package in Java?
A package and its sub-package are completely independent. java.util and java.util.stream are two separate packages with no shared visibility. Importing java.util.* does NOT import java.util.stream.Collectors — you must import the sub-package explicitly. Sub-package classes have no special access to parent-package members and vice versa. The folder structure creates the appearance of nesting, but the Java compiler treats each package as an entirely separate namespace.
Q4. What is the naming convention for Java packages?
Package names follow the reverse-domain-name convention to ensure global uniqueness. A company at flipkart.com uses com.flipkart as the prefix. The full name then adds the project and the architectural layer: com.flipkart.catalog.service for service classes in the catalog module. All segments are lowercase — no camelCase, no underscores recommended, no Java keywords. A class's fully qualified name is the complete package path plus the class name: com.flipkart.catalog.service.ProductService.
Q5. Where must the package declaration appear in a Java source file?
The package declaration must be the very first statement in the source file — before any import statements and before the class declaration. Only comments and blank lines may appear before it. The compiler enforces this strictly. The only exception is a class with no package declaration, which belongs to the default package. Having two package statements in one file or placing package after an import causes a compile error.
Q6. What is a fully qualified class name and when do you use it?
A fully qualified class name (FQCN) is the complete name of a class including its package: java.util.ArrayList, com.flipkart.order.model.Order. You use it when two classes from different packages have the same simple name in the same file — for example, if you need both java.util.Date and java.sql.Date, one must be referred to by its FQCN because you can only import one of them by simple name. FQCNs are also used in reflection (Class.forName("com.myapp.service.OrderService")) and in configuration files like Spring XML or persistence.xml.
FAQs
Can two classes in different packages have the same simple name?
Yes — that is precisely the problem packages solve. com.flipkart.order.Order and com.amazon.cart.Order are two completely different classes that happen to share the simple name Order. In a file that needs both, one must be imported by simple name and the other referenced by its FQCN. The compiler does not confuse them because the package prefix makes each name globally unique.
Does importing a package import all its classes?
import com.myapp.service.* imports all public classes directly in com.myapp.service — but not classes in its sub-packages, and not package-private classes. For sub-packages you need separate import statements. The wildcard * never imports sub-packages. Most style guides recommend specific imports over wildcards for readability — it is immediately clear which class from the package is actually used.
What happens if you have two classes with the same name imported?
The compiler raises an error if you try to import two classes with the same simple name. The fix is to import one and use the FQCN for the other: import java.util.Date; and then use java.sql.Date everywhere the SQL version is needed. Alternatively, remove both imports and use FQCNs for both.
Is java.lang automatically imported?
Yes. java.lang is the only package that is automatically imported in every Java source file without any explicit import statement. This is why String, System, Math, Integer, Object, Thread, and all other java.lang classes are available without importing. All other packages — including java.util — require explicit imports.
Can a package span multiple JAR files?
Yes. A package name does not have to be confined to one JAR or one directory. Multiple JARs on the classpath can contribute classes to the same package name — this is called a split package. While technically supported, split packages are discouraged in the Java module system (Java 9+) where each package must belong to exactly one module to ensure encapsulation and reliable linkage.
Summary
A package is a namespace that groups related classes and provides the foundation for Java's access control model. The package declaration must be the first statement in a source file. The name maps directly to the folder structure. Sub-packages are independent — java.util and java.util.stream share no visibility. The default package must be avoided in any production code.
The reverse-domain naming convention — com.company.project.layer — is the universal standard. It prevents collisions, communicates code structure, and satisfies all major frameworks that rely on package scanning. The layered organisation — model, service, repository, controller, util, exception — is the default starting point for any new Java project.
For interviews, be ready to explain the three purposes of packages, distinguish between a package and sub-package, explain the default package and its limitations, and describe the naming convention with a real example.
What to Read Next
Learn how to create your own package.