# Packages

Course: [Java](https://www.devtutorials.ai/learn/java) · Section: Packages and Access Control
Source: https://www.devtutorials.ai/learn/java/packages/packages-and-access-control

> Organise classes into packages: declare and import them, use built-in packages, build custom packages, control access across packages, and use static import.

Think about the folders on your computer.

You do not keep every file on the desktop. You put photos in a Photos folder, bills in a Bills folder, and school work in a School folder. Two files can even share a name, like `notes.txt`, as long as they sit in different folders.

Java organises classes the same way. A package is a folder for related classes.

In simple words: a package groups related classes together, and gives each class a full name that no other class can clash with.

## What You Will Learn

In this lesson, you will learn:

1. What a package is, and why Java uses them.
2. How to put a class in a package with the `package` statement.
3. How to use classes from other packages with `import`.
4. Which built-in packages you will use most often.
5. How to create your own packages and match them to folders.
6. How access modifiers behave across packages.
7. How static import works.
8. How to name packages the standard way.

## Start With a Working Example

Read the code, then look at the output below it.

```java readonly title="Classes from three different packages"
import java.util.ArrayList;
import java.time.LocalDate;

public class Main {
    public static void main(String[] args) {
        ArrayList<String> tasks = new ArrayList<>();
        tasks.add("Pay bill");
        tasks.add("Call Ravi");

        LocalDate due = LocalDate.of(2026, 10, 15);
        double root = Math.sqrt(144);

        System.out.println("Tasks: " + tasks);
        System.out.println("Due: " + due);
        System.out.println("Square root of 144: " + root);
    }
}
```

Output:

```text
Tasks: [Pay bill, Call Ravi]
Due: 2026-10-15
Square root of 144: 12.0
```

`ArrayList` comes from the `java.util` package. `LocalDate` comes from `java.time`. `Math` comes from `java.lang`.

The two `import` lines tell Java where to find the first two classes. `Math` needed no import, because `java.lang` is always available.

### Think About This

What if the line `import java.util.ArrayList;` were missing? The compiler would report `cannot find symbol: class ArrayList`, because Java no longer knows which package it lives in.

## What is a Package?

A **package** is a named group of related classes and interfaces.

Java itself is made of thousands of classes, arranged in packages:

- `java.lang` holds the core classes, like `String`, `Math` and `Integer`;
- `java.util` holds helpers, like `ArrayList`, `Arrays` and `Scanner`;
- `java.time` holds the date and time classes.

Packages give you three benefits.

### Organisation

Related classes live together. When you need date classes, you look in `java.time`.

### No Name Clashes

Two classes can have the same name if they are in different packages. Java has both `java.util.Date` and `java.sql.Date`. Their full names are different, so they never get mixed up.

### Access Control

Packages form a boundary for access. Some members can only be used by classes in the same package. You will see this later in the lesson.

### The Fully Qualified Name

Every class has a short name, like `ArrayList`. It also has a **fully qualified name**: its package name, a dot, then its short name.

```text
java.util.ArrayList
```

Think of a postal address. "Asha" is not enough to find someone. "Asha, 12 Lake Road, Chennai" is. The package works like the address.

## Package Declaration

To put a class in a package, write a **package declaration** at the very top of the file.

```text
package com.shop.billing;

public class Invoice {
    ...
}
```

Rules:

- It must be the **first statement** in the file. Only comments may come before it.
- A file can have **only one** package declaration.
- Every class in that file belongs to that package.
- A file with no package declaration is in the **default package**, which has no name. That is fine for small examples, like the cells in this course, but not for real projects.

```java readonly title="A class that declares its own package"
package com.syncshop.store;

public class Main {
    public static void main(String[] args) {
        System.out.println("Running in package: " + Main.class.getPackageName());
        System.out.println("Full class name: " + Main.class.getName());
    }
}
```

Output:

```text
Running in package: com.syncshop.store
Full class name: com.syncshop.store.Main
```

The class's full name now starts with the package name. Outside this package, other code would refer to it as `com.syncshop.store.Main`.

## Import Statement

To use a class from another package, you can write its full name every time:

```text
java.util.ArrayList<String> list = new java.util.ArrayList<>();
```

That gets long fast. An **import statement** lets you use the short name instead.

```text
import java.util.ArrayList;
```

Import statements go **after** the package declaration and **before** the class.

```text
package com.shop.billing;     // 1. package (optional)

import java.util.ArrayList;   // 2. imports

public class Invoice { ... }  // 3. the class
```

### Single-Type Import

Imports one class: `import java.util.ArrayList;`.

### On-Demand (Wildcard) Import

Imports every class in a package, using `*`: `import java.util.*;`.

The wildcard only covers classes directly in that package. It does **not** include sub-packages. `import java.util.*;` does not import `java.util.function.Predicate`.

### Classes That Need No Import

- Classes in **`java.lang`**, such as `String`, `Math` and `System`. Java imports this package for you.
- Classes in the **same package** as your class.

```java readonly title="Three ways to reach a class in another package"
import java.util.Arrays;
import java.time.*;

public class Main {
    public static void main(String[] args) {
        int[] scores = {72, 95, 81};
        Arrays.sort(scores);
        System.out.println("Single import: " + Arrays.toString(scores));

        LocalTime opens = LocalTime.of(9, 0);
        Duration shift = Duration.ofHours(8);
        System.out.println("Wildcard import: closes at " + opens.plus(shift));

        java.util.List<String> names = java.util.List.of("Asha", "Ravi");
        System.out.println("Full name, no import: " + names);
    }
}
```

Output:

```text
Single import: [72, 81, 95]
Wildcard import: closes at 17:00
Full name, no import: [Asha, Ravi]
```

`Arrays` came from a single-type import. `LocalTime` and `Duration` both came from the wildcard `java.time.*`. `List` was written with its full name, so it needed no import at all.

### When Names Clash

If two packages have a class with the same name, you cannot import both short names. Import one, and write the other one's full name.

```text
import java.util.Date;

Date today = new Date();                   // java.util.Date
java.sql.Date saved = java.sql.Date.valueOf("2026-10-07");   // full name
```

An import does not copy any code into your file, and it does not make your program bigger or slower. It only tells the compiler where to find a class name. A wildcard import is just as fast as a single import.

## Built-in Packages

Java comes with many ready-made packages. Here are the ones you will use most:

| Package | What it holds | Examples |
|---|---|---|
| `java.lang` | Core classes, imported automatically | `String`, `Math`, `Integer`, `System`, `Object` |
| `java.util` | Collections and general helpers | `ArrayList`, `HashMap`, `Arrays`, `Scanner`, `Random` |
| `java.util.function` | Functional interfaces for lambdas | `Predicate`, `Function`, `Consumer` |
| `java.time` | Dates and times | `LocalDate`, `LocalTime`, `Duration` |
| `java.io` | Reading and writing files and streams | `File`, `FileReader`, `IOException` |
| `java.nio.file` | Modern file handling | `Files`, `Path`, `Paths` |
| `java.math` | Very large and very exact numbers | `BigDecimal`, `BigInteger` |
| `java.net` | Networking | `URL`, `URI`, `HttpURLConnection` |
| `java.sql` | Databases | `Connection`, `ResultSet` |

```java readonly title="A few built-in packages at work"
import java.math.BigDecimal;
import java.util.HashMap;

public class Main {
    public static void main(String[] args) {
        HashMap<String, Integer> stock = new HashMap<>();
        stock.put("Pens", 40);
        stock.put("Notebooks", 15);
        System.out.println("Pens in stock: " + stock.get("Pens"));

        BigDecimal price = new BigDecimal("0.10");
        BigDecimal total = price.add(new BigDecimal("0.20"));
        System.out.println("Exact total: " + total);

        System.out.println("Bigger of 7 and 12: " + Math.max(7, 12));
    }
}
```

Output:

```text
Pens in stock: 40
Exact total: 0.30
Bigger of 7 and 12: 12
```

`HashMap` from `java.util` stores items by name. `BigDecimal` from `java.math` adds money values exactly, with no rounding surprises. `Math` from `java.lang` needed no import.

## Custom Packages

You create your own packages for your own classes. In a real project, each package matches a **folder**, and the folder path matches the package name exactly.

```text
src/
└── com/
    └── syncshop/
        ├── app/
        │   └── Main.java          package com.syncshop.app;
        ├── billing/
        │   └── Invoice.java       package com.syncshop.billing;
        └── model/
            └── Product.java       package com.syncshop.model;
```

Each dot in the package name becomes a folder level. `com.syncshop.billing` lives in the folder `com/syncshop/billing`.

### A Multi-File Example

**`src/com/syncshop/model/Product.java`**

```text
package com.syncshop.model;

public class Product {
    private final String name;
    private final int price;

    public Product(String name, int price) {
        this.name = name;
        this.price = price;
    }

    public String getName() { return name; }
    public int getPrice() { return price; }
}
```

**`src/com/syncshop/billing/Invoice.java`**

```text
package com.syncshop.billing;

import com.syncshop.model.Product;

public class Invoice {
    public static int total(Product... items) {
        int sum = 0;
        for (Product p : items) {
            sum += p.getPrice();
        }
        return sum;
    }
}
```

**`src/com/syncshop/app/Main.java`**

```text
package com.syncshop.app;

import com.syncshop.billing.Invoice;
import com.syncshop.model.Product;

public class Main {
    public static void main(String[] args) {
        Product pen = new Product("Pen", 20);
        Product bag = new Product("Bag", 499);
        System.out.println("Total: " + Invoice.total(pen, bag));
    }
}
```

### Compiling and Running

From the `src` folder, compile all the files, then run the main class by its **full name**:

```text
javac -d out com/syncshop/model/Product.java com/syncshop/billing/Invoice.java com/syncshop/app/Main.java
java -cp out com.syncshop.app.Main
```

Output:

```text
Total: 519
```

`-d out` tells `javac` to put the `.class` files in an `out` folder. It builds the matching package folders inside it. `-cp out` tells `java` where to look for classes.

In real projects, tools like IntelliJ IDEA, Eclipse, Maven or Gradle create the folders and run these commands for you.

The runnable cells in this course each hold a single file. So they cannot show several packages talking to each other. Copy the three files above into folders on your own computer to try a real multi-package project.

## Access Modifiers Across Packages

Packages change what each access modifier allows. The key idea is the package **boundary**.

| Modifier | Same class | Same package | Child class in another package | Any class in another package |
|---|---|---|---|---|
| `public` | ✓ | ✓ | ✓ | ✓ |
| `protected` | ✓ | ✓ | ✓ (through inheritance) | ✗ |
| default (no modifier) | ✓ | ✓ | ✗ | ✗ |
| `private` | ✓ | ✗ | ✗ | ✗ |

### public

Visible everywhere. Any class in any package can use it, after importing it.

### protected

Visible inside the same package, **plus** to child classes in other packages. A child in another package can use a protected member on itself (through `this` or `super`), but not on some other object of the parent type.

### default (package-private)

Visible **only inside the same package**. This is what you get when you write no modifier. It is useful for helper classes that the rest of the program should not touch.

### private

Visible only inside its own class, whatever the package.

### Example Across Two Packages

```text
// File: com/bank/core/Account.java
package com.bank.core;

public class Account {
    public    String owner = "Asha";     // everyone
    protected int    balance = 1000;      // package + children
              String branch = "Chennai";  // package only
    private   String pin = "4821";        // this class only
}
```

```text
// File: com/bank/app/Main.java
package com.bank.app;

import com.bank.core.Account;

public class Main {
    public static void main(String[] args) {
        Account a = new Account();
        System.out.println(a.owner);    // ✓ public
        System.out.println(a.balance);  // ✗ protected, and Main is not a child
        System.out.println(a.branch);   // ✗ default, different package
        System.out.println(a.pin);      // ✗ private
    }
}
```

Only `owner` compiles. The compiler reports `balance has protected access in Account`, `branch is not public in Account; cannot be accessed from outside package`, and `pin has private access in Account`.

```text
// File: com/bank/app/SavingsAccount.java
package com.bank.app;

import com.bank.core.Account;

public class SavingsAccount extends Account {
    void show() {
        System.out.println(owner);     // ✓ public
        System.out.println(balance);   // ✓ protected: this is a child class
        System.out.println(branch);    // ✗ default: different package
    }
}
```

`SavingsAccount` is in another package, but it is a child of `Account`. So it can use the `protected` field `balance`, but not the package-private `branch`.

### Classes Have Access Too

A top-level class can only be `public` or default:

- A **`public` class** can be used from any package.
- A **default class** (no modifier) can only be used inside its own package.

A public class must live in a file with the same name, such as `Account.java`.

**Easy Way to Remember:** `private` = **my class**. Default = **my package**. `protected` = **my package plus my children**. `public` = **everyone**.

## Static Import

A normal import lets you skip the **package** name. A **static import** lets you skip the **class** name too, for static members.

```text
import static java.lang.Math.PI;        // one static member
import static java.lang.Math.*;         // every static member of Math
```

After this, you can write `PI` and `sqrt(16)` instead of `Math.PI` and `Math.sqrt(16)`.

```java readonly title="Static import removes the class name"
import static java.lang.Math.PI;
import static java.lang.Math.pow;
import static java.lang.Math.sqrt;

public class Main {
    public static void main(String[] args) {
        double radius = 3;

        double area = PI * pow(radius, 2);
        double side = sqrt(81);

        System.out.println("Area rounded: " + Math.round(area));
        System.out.println("Side: " + side);
    }
}
```

Output:

```text
Area rounded: 28
Side: 9.0
```

`PI`, `pow` and `sqrt` are used without `Math.` in front. `Math.round` was not statically imported, so it still needs `Math.`.

Use static import sparingly. Without the class name, a reader may not know where `pow` came from. It works best for well-known constants and for a few methods used many times in one file.

| | Normal import | Static import |
|---|---|---|
| Written as | `import java.util.Arrays;` | `import static java.lang.Math.PI;` |
| Imports | A class | Static fields and methods |
| Lets you write | `Arrays.sort(a)` instead of `java.util.Arrays.sort(a)` | `PI` instead of `Math.PI` |

## Package Naming Conventions

Package names follow a few standard rules, so names stay unique around the world.

### Use Lowercase

Package names are all lowercase: `com.syncshop.billing`, never `com.SyncShop.Billing`.

### Start With Your Domain, Reversed

Organisations start their package names with their web domain, written backwards:

| Domain | Package prefix |
|---|---|
| `syncfusion.com` | `com.syncfusion` |
| `example.org` | `org.example` |
| `myschool.edu.in` | `in.edu.myschool` |

No two organisations own the same domain, so no two will choose the same package names.

### Then Add the Project and the Area

After the domain, add the project name, then the part of the project:

```text
com.syncshop.app
com.syncshop.billing
com.syncshop.model
com.syncshop.util
```

### Avoid These

- Names starting with `java` or `javax`. Those are reserved for Java itself.
- Hyphens and spaces. Use underscores if you must: `com.example.my_app`.
- Java keywords, like `int` or `class`, as a part of the name.
- Starting a part with a digit. Write `com.example._2fa` rather than `com.example.2fa`.

| Good | Bad | Problem |
|---|---|---|
| `com.syncshop.billing` | `Com.SyncShop.Billing` | Capital letters |
| `org.cityschool.exams` | `exams` | Not unique |
| `com.example.my_app` | `com.example.my-app` | Hyphen is not allowed |
| `in.ravi.games` | `java.ravi.games` | `java` is reserved |

## Common mistakes

The following mistakes are common when using packages and access modifiers. Each row shows what you see, why it happens and how to fix it.

| Symptom | Cause | Fix |
|---|---|---|
| `class, interface, enum, or record expected` | `package` is not the first statement | Move it to the top |
| `cannot find symbol: class X` | The class's package was not imported | Add the import, or use the full name |
| A class cannot be found at run time | The folder does not match the package | Make folders match the package name |
| `is not public ...; cannot be accessed from outside package` | A default member was used from another package | Make it `public`, or add a public method |
| `has protected access` | A non-child class in another package used a protected member | Use a public method, or make it a child class |
| `Could not find or load main class` | The class was run by its short name | Run it by its full name |

## What to Remember

- A package groups related classes. It gives each class a full name, like `java.util.ArrayList`.
- `package` must be the first statement in a file. Folders must match the package name.
- `import` lets you use a class's short name. `java.lang` and same-package classes need no import.
- Use built-in packages like `java.util`, `java.time`, `java.io` and `java.math` instead of writing everything yourself.
- `public` is visible everywhere, `protected` to the package and child classes, default only to the package, and `private` only to the class.
- Static import lets you use static members, like `PI`, without the class name.
- Name packages in lowercase, starting with your domain reversed: `com.company.project.area`.

Next: Generics Fundamentals
