Packages, imports and project structure
A package groups related classes and gives them a unique name, like com.javaatlas.billing.Invoice. The convention is your domain name reversed, then the feature.
- The package declaration is the first line:
package com.javaatlas.billing; - The folders match it:
src/main/java/com/javaatlas/billing/Invoice.java importlets you use short names:import java.util.List;. Classes injava.lang(String,Math) need no import.import staticbrings in static members:import static java.lang.Math.max;
Access levels decide what other packages can see: public (everyone), protected (the package and subclasses), no keyword (the package only), private (the class only).
In Maven and Gradle projects, code lives in src/main/java, tests in src/test/java and settings in src/main/resources. Organise packages by feature (billing, catalog) rather than by layer (controllers, services) so related code stays together.
Example
// src/main/java/com/javaatlas/billing/Invoice.java
package com.javaatlas.billing;
import java.math.BigDecimal;
import java.util.List;
import static java.util.Objects.requireNonNull;
public class Invoice { // visible everywhere
private final List<Line> lines; // visible only inside Invoice
public Invoice(List<Line> lines) {
this.lines = List.copyOf(requireNonNull(lines));
}
BigDecimal total() { // package-private: billing package only
return lines.stream().map(Line::amount).reduce(BigDecimal.ZERO, BigDecimal::add);
}
}
record Line(String item, BigDecimal amount) {} // package-private recordsrc/main/java/com/javaatlas
├── JavaAtlasApplication.java
├── billing/ Invoice, InvoiceService, InvoiceController
├── catalog/ Course, CourseService, CourseController
└── common/ shared errors and configuration
src/test/java/com/javaatlas/billing/InvoiceServiceTest.java
src/main/resources/application.ymlCommon mistake
Putting the Spring Boot main class in a sub-package. Component scanning starts from its package, so classes in sibling packages aren't found.
Under the hood
Package-private access is underused: keep classes package-private and expose only the few types other features need, and the compiler enforces your boundaries. Modules (Java 9) add a stronger layer, exporting only chosen packages. Wildcard imports compile to the same bytecode as explicit ones; teams usually prefer explicit imports for readability.
Check yourself
Which package is imported automatically?
How this connects
Know these first
Where this leads
Part of Java from zero.
Was this lesson helpful?
Finished reading? Mark it complete to track your progress.