skip to content

What is a package declaration in Java, and how does it relate to the directory structure of your source files?

level: juniorimportance: must knowfreq 70%

answer

  1. First statement in the file; at most one
  2. Dots in package name = directory separators
  3. Maps onto folders under the source root
  4. FQN = package + class name
  5. Mapping exists because the class loader finds bytecode by path

basics

~20 s

A package declaration is the first line of code in a Java file, like package com.example.app;. It groups related classes under a name. The folders on disk must match the package name: com.example.app lives in com/example/app/.

solid answer

~40 s

A package is a namespace that groups related Java types (classes, interfaces, enums). You declare it with `package some.name;` as the very first statement in the source file, before any imports. The package name maps directly onto the folder hierarchy under your source root: a class in package `com.example.app` must sit in the directory `com/example/app/`. This mapping lets the compiler and JVM locate the `.class` file by name. Packages prevent name collisions (two `Order` classes can coexist in different packages), control access (package-private members are visible only within the same package), and organize large codebases logically. If the declared package and the physical directory disagree, the compiler reports an error.

go deeper

for a junior

Can write a correct package declaration and place the file in the matching folder; knows it must be the first line.

for a middle

Explains the package-to-directory mapping and the fully qualified name, and why a mismatch breaks the build.

for a senior

Connects the mapping to class loading on the classpath and uses packages as an encapsulation/access-control boundary, not just organization.

for a principal

Reasons about package design at scale: layering, module boundaries (JPMS), avoiding cyclic package dependencies, and how package structure interacts with build tooling and class loaders.

## What problem packages solve Imagine a project with hundreds of classes. Without any grouping, every class name would have to be globally unique, and finding a class would be chaos. A **package** is Java's solution: a named container that groups related types together. A *type* means a class, interface, enum, record, or annotation. Think of packages like folders for files on your computer, or like postal addresses: `com.example.billing.Invoice` is a full address that uniquely identifies one class, the way a street address identifies one house even if many houses are called "number 5". ## The package declaration The **package declaration** is a single line that must be the **first statement** in a `.java` file (comments and blank lines may come before it, but no other code): ```java package com.example.billing; ``` After this line come your `import` statements, then your class/interface definitions. A file may have **at most one** package declaration. If you omit it entirely, the file belongs to the *default (unnamed) package* (covered in another question). ## Fully qualified names The package name combined with the type name gives the **fully qualified name (FQN)**. For a class `Invoice` in package `com.example.billing`, the FQN is `com.example.billing.Invoice`. The FQN is globally unique and is how the compiler, the JVM, and tools refer to the class unambiguously. When you `import com.example.billing.Invoice;`, you are telling the compiler the FQN so you can then write just `Invoice` in your code. ## The directory mapping Here is the rule every Java developer must internalize: **the package name must mirror the directory path** of the source file, relative to the *source root* (the base directory the compiler treats as the top of the package tree, e.g. `src/main/java` in a Maven/Gradle project). - Package `com.example.billing` → directory `com/example/billing/` - A file declaring `package com.example.billing;` named `Invoice.java` must live at `<source-root>/com/example/billing/Invoice.java`. Each dot in the package name becomes a directory separator. The compiler enforces this: if `Invoice.java` declares `package com.example.billing;` but sits in `com/example/sales/`, you get a compile error ("declared package does not match the expected package" with tools like Maven, or the class simply cannot be found at the expected location). ## Why the mapping exists The JVM finds compiled `.class` files by translating the FQN into a path on the *classpath*. `com.example.billing.Invoice` is loaded from `com/example/billing/Invoice.class` somewhere on the classpath (a directory or inside a JAR). If the on-disk layout did not match the package name, the class loader could not find the bytecode. So the directory-equals-package rule is not arbitrary style; it is how class loading physically works. ## What packages give you 1. **Namespacing** — two classes named `Order` can coexist as `com.shop.Order` and `com.warehouse.Order`. 2. **Access control** — members with no access modifier (`package-private`, the default) are visible only to other types in the *same* package. Packages are thus a unit of encapsulation. 3. **Organization** — related code is grouped, making large systems navigable. ## Summary A package declaration names the namespace a type belongs to; it must be the first line of the file; and the package name must exactly match the directory hierarchy under the source root, because that mapping is how compiled classes are physically located and loaded.

  • What happens if the declared package doesn't match the file's directory?
    The compiler cannot place the class where its fully qualified name expects, so the build fails: Maven/Gradle report a package-mismatch error, and even raw javac will fail to find or load the class at the path implied by its FQN.
  • Can comments appear before the package declaration?
    Yes. Comments and blank lines are allowed before it; the package declaration just must be the first actual statement (before imports and type definitions).

saying these in an interview costs you the question

  • Thinking the package name is independent of folder location
  • Believing you can put a class anywhere on disk regardless of its declared package
  • Confusing the package declaration with an import statement
  • Saying a file can have multiple package declarations

context