---
title: "Packages, modules, reflection, and annotations"
chapter: "14"
---

# Packages, modules, reflection, and annotations

Packages organize names. The Java Platform Module System adds explicit
dependencies and strong encapsulation.

## Packages

Package names should follow stable ownership and capability. Package-private
visibility is a useful architectural boundary. Avoid dumping unrelated types
into `util`.

## Modules

A module descriptor can `requires` another module, `exports` packages to
consumers, `opens` packages for deep reflection, `uses` services, and
`provides` implementations. `exports` is compile/runtime access; `opens`
permits reflective access.

The module path uses named modules. The classpath places code in the unnamed
module. Automatic modules help migration but names and boundaries need care.
`jlink` can create a custom runtime containing selected modules.

## Reflection

Reflection inspects and invokes types dynamically. It enables frameworks,
serialization, tests, and tools, but weakens compile-time visibility and can
cross encapsulation only with allowed access. Cache reflective metadata when
appropriate and avoid using reflection to hide normal design.

## Annotations

Retention can be SOURCE, CLASS, or RUNTIME. Targets restrict where annotations
apply. Annotation processors generate/validate code at compile time; reflection
reads runtime annotations.

## ServiceLoader

The service-provider mechanism discovers implementations without hard-coding
them. Modules can declare `uses` and `provides`.

## Feynman check

A package is a labeled room. A module is a building permit listing which rooms
outsiders may enter and which other buildings it depends on. `opens` grants a
special inspector access.
