Packages

By the Syncfusion DevTutorials team · Last updated

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.

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:

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.

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.

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.

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:

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:

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

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

import java.util.ArrayList;

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

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.

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:

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.

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:

PackageWhat it holdsExamples
java.langCore classes, imported automaticallyString, Math, Integer, System, Object
java.utilCollections and general helpersArrayList, HashMap, Arrays, Scanner, Random
java.util.functionFunctional interfaces for lambdasPredicate, Function, Consumer
java.timeDates and timesLocalDate, LocalTime, Duration
java.ioReading and writing files and streamsFile, FileReader, IOException
java.nio.fileModern file handlingFiles, Path, Paths
java.mathVery large and very exact numbersBigDecimal, BigInteger
java.netNetworkingURL, URI, HttpURLConnection
java.sqlDatabasesConnection, ResultSet

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:

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.

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

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

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

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:

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:

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.

ModifierSame classSame packageChild class in another packageAny 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

// 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
}
// 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.

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

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

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:

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 importStatic import
Written asimport java.util.Arrays;import static java.lang.Math.PI;
ImportsA classStatic fields and methods
Lets you writeArrays.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:

DomainPackage prefix
syncfusion.comcom.syncfusion
example.orgorg.example
myschool.edu.inin.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:

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.
GoodBadProblem
com.syncshop.billingCom.SyncShop.BillingCapital letters
org.cityschool.examsexamsNot unique
com.example.my_appcom.example.my-appHyphen is not allowed
in.ravi.gamesjava.ravi.gamesjava 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.

SymptomCauseFix
class, interface, enum, or record expectedpackage is not the first statementMove it to the top
cannot find symbol: class XThe class's package was not importedAdd the import, or use the full name
A class cannot be found at run timeThe folder does not match the packageMake folders match the package name
is not public ...; cannot be accessed from outside packageA default member was used from another packageMake it public, or add a public method
has protected accessA non-child class in another package used a protected memberUse a public method, or make it a child class
Could not find or load main classThe class was run by its short nameRun 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