Annotations in Java
Explore how Java annotations add metadata to classes and methods without affecting execution. Understand built-in annotations like @Override and @Deprecated, learn to create custom annotations with meta-annotations like @Target and @Retention, and discover how reflection reads these at runtime to support frameworks and declarative code.
We'll cover the following...
We have just learned how to use Reflection to inspect classes and methods from the outside. However, we often need to leave instructions inside the code itself. Annotations allow us to attach labels to methods and classes that describe intent without changing program execution. For example, we can tag a method to run before others or mark a class for database storage.
While Reflection provides the ability to inspect code structure, annotations provide the specific instructions that tell tools what that code is meant to do. This combination drives many modern Java frameworks, allowing us to write declarative code that handles complex tasks automatically.
Understanding metadata and built-in annotations
Annotations are metadata about data. They do not directly change how a method executes; instead, they provide information to the compiler or the runtime environment. We have already seen a few of these in earlier lessons without explicitly analyzing them.
To understand exactly how they work, we will look at Java’s three most common built-in annotations separately.
1. The compiler check: @Override
The @Override annotation guarantees that a method actually overrides a method from a superclass or interface. This is a safety mechanism. If we misspell the method name or get the parameters wrong, the compiler will catch the error immediately.
Line 11: We place
@Overrideabove the method. If we accidentally typedpublic void generateReprt(), the compiler would stop with an error: “method does not override or implement a method from a supertype.”
2. The warning signal: @Deprecated
The @Deprecated annotation marks a class or method as obsolete. It tells other developers (and the compiler) that this code should no longer be used, likely because a better alternative exists. ...