How does @Deprecated work, and what do its since and forRemoval elements mean?
answer
- Advisory, not an error — emits a compiler warning at use sites
- RUNTIME retention -> visible via reflection
- since = version/date string; forRemoval = boolean (Java 9, JEP 277)
- forRemoval=true -> stronger 'removal' warning (terminal deprecation)
- Pair the annotation with the Javadoc @deprecated tag naming the replacement
- Suppress with @SuppressWarnings("deprecation") or "removal"
basics
~20 s@Deprecated marks code that should no longer be used. The compiler warns anyone who uses it. Since Java 9 you can add since="version" to say when it was deprecated and forRemoval=true to warn it will be deleted in a future release.
solid answer
~40 s@Deprecated is a standard java.lang annotation that flags a program element (class, method, field, etc.) as obsolete and discouraged. The compiler emits a deprecation warning at every use site, nudging callers to migrate. It is retained at runtime (RUNTIME retention) so tools and the JVM can inspect it. Java 9 added two elements: since, a free-form string naming the version/date when it was deprecated, and forRemoval, a boolean. When forRemoval=true, the element is scheduled for deletion in a future release, and the compiler issues a stronger 'removal' warning that you cannot suppress with the same blanket settings — signaling 'migrate now,' versus ordinary deprecation which means 'avoid in new code.' Best practice is to always pair @Deprecated with a Javadoc @deprecated tag explaining the replacement. You suppress deprecation warnings with @SuppressWarnings("deprecation") (or "removal").
code
java · 12 linespublic class LegacyApi {
/**
* @deprecated Use {@link #fetch(String)} instead.
*/
@Deprecated(since = "3.0", forRemoval = true)
public String get() { return fetch("default"); }
public String fetch(String key) { return "..."; }
}
// Caller:
// new LegacyApi().get(); // compiler emits a 'removal' warninggo deeper
Knows @Deprecated marks old code and produces a warning; uses it without breaking the build.
Explains since/forRemoval semantics, the runtime retention, and pairing with the Javadoc @deprecated tag and a replacement pointer.
Designs deprecation lifecycles for an evolving API, distinguishes ordinary vs terminal (forRemoval) deprecation, and manages the "deprecation"/"removal" suppression categories.
Sets org-wide API evolution policy: SemVer mapping, deprecation-to-removal windows, automated migration tooling, and CI gates on new deprecated usage.
## What it is `@Deprecated` is a built-in annotation in `java.lang` you place on a program element (class, interface, method, constructor, field, enum constant, module, etc.) to say: **this still works, but you should stop using it; a better alternative exists or it will go away.** It is part of API lifecycle management — a way to evolve a library without breaking existing callers immediately. ## What happens when you use deprecated code When the compiler sees you **reference** a deprecated element, it prints a **deprecation warning**. The code still compiles and runs — deprecation is advisory, not an error. The annotation has **`RetentionPolicy.RUNTIME`**, meaning it stays in the compiled `.class` file and is visible via reflection, so IDEs, linters, and the JVM can detect deprecated usage at any stage. ## The Javadoc twin There are two related things with the same word: - The **annotation** `@Deprecated` (machine-readable, drives the warning). - The **Javadoc tag** `@deprecated <text>` (human-readable, in a comment). Best practice is to use **both**: the annotation triggers tooling, and the Javadoc tag tells the reader *why* and *what to use instead*. ```java /** * @deprecated Use {@link #computeV2(int)} instead; this ignores overflow. */ @Deprecated(since = "2.4", forRemoval = true) public int compute(int x) { ... } ``` ## The two elements (added in Java 9) Before Java 9, `@Deprecated` was a **marker** (no elements). Java 9 (JEP 277) added: - **`since`** — a `String` documenting **when** the element was deprecated (typically the release version or a date). Default is the empty string. It is informational only. - **`forRemoval`** — a `boolean`, default `false`. When **`true`**, it declares the element is **planned for removal** in a future release. This is a stronger commitment than ordinary deprecation. ### Ordinary vs terminal deprecation - `forRemoval = false` (default): **'avoid in new code'** — the element may live indefinitely. Compiler emits a normal deprecation warning. - `forRemoval = true`: **'migrate now, it's going away'** — the compiler emits a distinct **removal warning**, and it is treated more seriously by tools. This is sometimes called *terminal deprecation*. ## Suppressing the warnings You silence deprecation warnings with `@SuppressWarnings("deprecation")`. For `forRemoval=true` elements, the relevant category is **`"removal"`**. You suppress only when you have a legitimate reason (e.g., a compatibility shim that must still call the old API). ## Why this matters Deprecation is the backbone of **backward-compatible API evolution**: you introduce a replacement, deprecate the old path with `since` + a Javadoc pointer, optionally mark `forRemoval` once you commit to deleting it, and finally remove it in a later major version. The JDK itself uses this heavily (e.g., `Thread.stop()`, finalization, many `java.util.Date` methods). ## Takeaway Use `@Deprecated` + `@deprecated` Javadoc together; add `since` for traceability; reserve `forRemoval=true` for APIs you're committed to deleting, and suppress with the matching `"deprecation"`/`"removal"` category only when justified.
- What is the difference between @Deprecated with forRemoval=false versus forRemoval=true?false (default) means 'avoid in new code' and the element may persist; true means it is scheduled for removal in a future release and triggers a stronger, separate 'removal' warning.
- What retention policy does @Deprecated have and why does it matter?RUNTIME retention, so it survives into the .class file and is visible via reflection, letting IDEs, linters, and the JVM detect deprecated usage at runtime/analysis time.
saying these in an interview costs you the question
- Saying deprecated code won't compile or won't run
- Confusing the annotation @Deprecated with the Javadoc @deprecated tag (you want both)
- Thinking since/forRemoval existed before Java 9
- Believing forRemoval=true immediately removes the element
- Suppressing forRemoval warnings with the "deprecation" category instead of "removal"