Skip to content

Packages and Imports — Naming Conventions, import, module-info.java, and JPMS

DodaTech Updated 2026-06-28 5 min read

In this tutorial, you will learn about Packages and Imports. We cover key concepts, practical examples, and best practices to help you master this topic.

Java packages organize classes into namespaces, preventing name collisions and enabling access control. Without packages, every class in every library would share a single namespace — two libraries could not both have a User class. Packages solve this by grouping related classes under a unique namespace.

What You'll Learn

  • Package declaration and directory structure
  • Import statements: explicit, on-demand, and static imports
  • Package-level access control
  • The Java Platform Module System (JPMS)

Why It Matters

Package organization affects maintainability, build configuration, and deployment. Modular Java applications require module-info.java. Understanding packages is essential for working with any real-world Java project.

Real-World Use

Spring Boot projects follow a layered package structure (controller, service, repository, model). Libraries like Apache Commons use org.apache.commons.lang3. Every Java project relies on packages.


Package Declaration

Every Java file starts with a package declaration (or uses the unnamed package):

package com.example.myapp;

public class User {
    // ...
}

The package name must match the directory structure: com/example/myapp/User.java.

Naming Convention

  • Domain reversed: com.example, org.apache, io.spring
  • All lowercase: Even acronyms: com.example.htmlparser
  • One level per sub-namespace: com.example.myapp.service

The Import Statement

Import brings types from other packages into scope:

import java.util.List;
import java.util.ArrayList;

On-Demand Import (Wildcard)

import java.util.*; // imports all types in java.util

Wildcard imports do not import nested packages (java.util.* does not include java.util.stream.*). They also do not hurt performance — the compiler resolves specific types.

Name Conflicts

If two packages have a class with the same name, use fully qualified names:

import java.util.Date;
// import java.sql.Date; // conflict — use fully qualified

java.sql.Date sqlDate = new java.sql.Date(System.currentTimeMillis());

Static Imports

Static imports allow using static members without the class name:

import static java.lang.Math.PI;
import static java.lang.Math.sqrt;
import static java.util.Collections.sort;

double area = PI * r * r;
double root = sqrt(25);
sort(list);

Use static imports sparingly — they can harm readability when overused.

Package-Level Access

When a member has no access modifier (package-private), it is accessible from any class in the same package:

package com.example.myapp;

class Helper { // package-private class
    static void utility() { // package-private method
        System.out.println("Utility");
    }
}
package com.example.myapp;

public class Main {
    public static void main(String[] args) {
        Helper.utility(); // accessible (same package)
    }
}

The Java Module System (JPMS, Java 9+)

JPMS adds a new layer of Encapsulation above packages. A module is a group of packages that explicitly declares which packages it exports and which modules it requires.

module-info.java

module com.example.myapp {
    requires java.sql;          // depends on java.sql module
    exports com.example.myapp.api;  // publicly accessible packages
    exports com.example.myapp.model;
}

Key Directives

  • requires — declares a dependency on another module
  • exports — makes a package accessible to other modules
  • opens — allows reflective access (for frameworks like Spring/Hibernate)
  • provides ... with ... — service provider interface
  • uses — declares a dependency on a service

Benefits

  • Strong encapsulation: Internal packages are hidden by default
  • Reliable configuration: requires prevents missing dependencies at startup
  • Smaller footprint: The JDK itself is modularized — java.base is always available, other modules are loaded on demand

The java.base Module

java.base is always required and does not need an explicit requires. It includes java.lang, java.util, java.io, java.math, and other fundamental packages.

Common Mistakes

  1. Forgetting the package declaration. Classes in the unnamed package cannot be imported by classes in named packages. Always declare a package.
  2. Using wildcard imports excessively. While they do not affect performance, they make it harder to see exactly which classes are used.
  3. Naming packages with uppercase letters. Package names should be all lowercase, even for acronyms.
  4. Missing exports in modules. A package that is not exported is invisible to other modules, even with Reflection (unless opens is used).
  5. Adding module-info.java to the default package. Module declarations require a named package.

Practice Questions

1. What is the purpose of a Java package?
To organize classes into namespaces, avoid name collisions, and enable access control.

2. How does the on-demand import (import java.util.*) affect performance?
It does not. The compiler resolves which types are actually used. Wildcard imports are a compile-time convenience with no runtime cost.

3. What is the difference between exports and opens in a module?
exports makes the public types in a package accessible at compile time and runtime. opens allows reflective access (for frameworks like Spring) without making the types compile-time accessible.

4. What module is implicitly required in every module?
java.base. It is always present and does not need an explicit requires directive.

5. Can two classes have the same name if they are in different packages?
Yes. Use fully qualified names to distinguish them, or import one and use the fully qualified name for the other.

Challenge Question:
Create a multi-module project with two packages (without Maven/Gradle, just manual compilation). Create com.example.lib with a Greeter class and com.example.app with a Main class. Use module-info.java to export only the com.example.lib package. Compile and run using javac and java with --module-path.

FAQ

What is the unnamed package?

The unnamed package is the default package for Java files without a package declaration. Classes in the unnamed package cannot be imported by classes in named packages. Modern Java projects should never use the unnamed package.

What is the difference between `import` and `requires`?

import is a compile-time declaration that lets you use short names for types. requires is a module directive that declares a dependency on another module at both compile time and runtime.

Can a module export a package to only specific modules?

Yes, using exports ... to .... Example: exports com.example.internal to com.example.test; restricts access to the specified module.

What happens if I forget module-info.java in Java 9+?

Your code still works as an unnamed module. Unnamed modules can access all JDK modules (like the classpath does), but they lose the encapsulation benefits of JPMS.

How do I create a multi-module project without Maven?

Create separate directories for each module, each with its own module-info.java. Compile with javac -d output/module1 src/module1/... and run with java --module-path output --module module1/com.example.Main.

Mini Project

Write a program PackageDemo.java organized in the following structure:

src/
  com.example.lib/
    Greeter.java   (package com.example.lib)
    module-info.java
  com.example.app/
    Main.java      (package com.example.app)
    module-info.java
  • Greeter has a public method greet(String name) that returns "Hello, " + name
  • Main imports and uses Greeter
  • module-info.java for com.example.lib exports its package
  • module-info.java for com.example.app requires com.example.lib
  • Compile with javac commands and run with java --module-path

What's Next

Packages organize classes, but Java also provides special types for specific use cases. Lesson 18 covers enums — type-safe constants with fields, methods, and specialized collections like EnumMap and EnumSet.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro