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:
- What a package is, and why Java uses them.
- How to put a class in a package with the
packagestatement. - How to use classes from other packages with
import. - Which built-in packages you will use most often.
- How to create your own packages and match them to folders.
- How access modifiers behave across packages.
- How static import works.
- 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.langholds the core classes, likeString,MathandInteger;java.utilholds helpers, likeArrayList,ArraysandScanner;java.timeholds 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 asString,MathandSystem. 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:
| 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 |
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.
| 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
// 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
publicclass 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 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:
com.syncshop.app
com.syncshop.billing
com.syncshop.model
com.syncshop.util
Avoid These
- Names starting with
javaorjavax. Those are reserved for Java itself. - Hyphens and spaces. Use underscores if you must:
com.example.my_app. - Java keywords, like
intorclass, as a part of the name. - Starting a part with a digit. Write
com.example._2farather thancom.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. packagemust be the first statement in a file. Folders must match the package name.importlets you use a class's short name.java.langand same-package classes need no import.- Use built-in packages like
java.util,java.time,java.ioandjava.mathinstead of writing everything yourself. publicis visible everywhere,protectedto the package and child classes, default only to the package, andprivateonly 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