3 Enhanced Deprecation
The semantics of what deprecation means has been clarified, including whether an API may be removed in the near future.
If you are a library maintainer, you can take advantage of the updated deprecation syntax to inform users of your library about the status of APIs provided by your library.
If you are a library or application developer, you can use the jdeprscan
tool to find uses of deprecated JDK API elements in your applications or libraries.
Deprecation in the JDK
Deprecation is a notification to library consumers that they should migrate code from a deprecated API.
-
The API is dangerous (for example, the Thread.stop method).
-
There is a simple rename (for example, AWT Component.show/hide replaced by setVisible).
-
A newer, better API can be used instead.
-
The deprecated API is going to be removed.
In prior releases, APIs were deprecated but virtually never removed. Starting with JDK 9, APIs may be marked as deprecated for removal. This indicates that the API is eligible to be removed in the next release of the JDK platform. If your application or library consumes any of these APIs, then you should make a plan to migrate from them soon.
For a list of deprecated APIs in the current release of the JDK, see the Deprecated API page in the API specification.
How to Deprecate APIs
Deprecating an API requires using two different mechanisms: the @Deprecated annotation and the @deprecated Javadoc tag.
The @Deprecated annotation marks an API in a way that is recorded in the class file and is available at runtime. This allows various tools, such as javac
and jdeprscan
, to detect and flag usage of deprecated APIs. The @deprecated Javadoc tag is used in documentation of deprecated APIs, for example, to describe the reason for deprecation, and to suggest alternative APIs.
Note the capitalization: the annotation starts with an uppercase D and the Javadoc tag starts with a lowercase d.
Using the @Deprecated Annotation
To indicate deprecation, precede the module, class, method, or member declaration with @Deprecated. The annotation contains these elements:
-
@Deprecated(since="
<version>
")-
<version> is the version when the API was deprecated. This is for informational purposes. The default is the empty string (
"
"
).
-
-
@Deprecated(forRemoval=
<boolean>
)-
forRemoval=true indicates that the API is subject to removal in a future release.
-
forRemoval=false recommends that code should no longer use this API; however, there is no current intent to remove the API. This is the default value.
-
For example: @Deprecated(since="9", forRemoval=true)
-
Deprecated.
-
Deprecated, for removal: This API element is subject to removal in a future version.
The javadoc
tool generates a page named deprecated-list.html
which contains the list of deprecated APIs, and adds a link in the navigation bar to that page.
The following is a simple example of using the @Deprecated annotation from the java.lang.Thread class:
public class Thread implements Runnable {
...
@Deprecated(since="1.2")
public final void stop() {
...
}
...
Semantics of Deprecation
The two elements of the @Deprecated annotation give developers the opportunity to clarify what deprecation means for their exported APIs.
-
@Deprecated(forRemoval=true) indicates that the API is eligible to be removed in a future release of the JDK platform.
-
@Deprecated(since="
<version>
") contains the JDK version string that indicates when the API element was deprecated, for those deprecated in JDK 9 and beyond.
If you maintain libraries and produce your own APIs, then you probably use the @Deprecated annotation. You should determine and communicate your policy around API removals. For example, if you release a new library every 6 weeks, then you may choose to deprecate an API for removal, but not remove it for several months to give your customers time to migrate.
Using the @deprecated Javadoc Tag
Use the @deprecated tag in the javadoc comment of any deprecated program element to indicate that it should no longer be used (even though it may continue to work). This tag is valid in all class, method, or field documentation comments. The @deprecated tag must be followed by a space or a newline. In the paragraph following the @deprecated tag, explain why the item was deprecated, and suggest what to use instead. Mark the text that refers to new versions of the same functionality with an @link tag.
javadoc
tool moves the text following the @deprecated tag to the front of the description and precedes it with a warning. For example, this source: /**
* ...
* @deprecated This method does not properly convert bytes into
* characters. As of JDK 1.1, the preferred way to do this is via the
* {@code String} constructors that take a {@link
* java.nio.charset.Charset}, charset name, or that use the platform's
* default charset.
* ...
*/
@Deprecated(since="1.1")
public String(byte ascii[], int hibyte) {
...
generates the following output:
@Deprecated(since="1.1")
public String(byte[] ascii,
int hibyte)
Deprecated. This method does not properly convert bytes into characters. As of
JDK 1.1, the preferred way to do this is via the String constructors that take a
Charset, charset name, or that use the platform's default charset.
If you use the @deprecated Javadoc tag without the corresponding @Deprecated annotation, a warning is generated.
Notifications and Warnings
When an API is deprecated, developers must be notified. The deprecated API may cause problems in your code, or, if it is eventually removed, cause failures at run time.
The Java compiler generates warnings about deprecated APIs. There are options to generate more information about warnings, and you can also suppress deprecation warnings.
Compiler Deprecation Warnings
If the deprecation is forRemoval=false
, the Java compiler generates an "ordinary deprecation warning". If the deprecation is forRemoval=true
, the compiler generates a "removal warning".
The two kinds of warnings are controlled by separate -Xlint
flags: -Xlint:deprecation
and -Xlint:removal
. The javac -Xlint:removal
option is enabled by default, so removal warnings are shown.
The warnings can also be turned off independently (note the "–"): -Xlint:-deprecation
and -Xlint:-removal
.
This is an example of an ordinary deprecation warning.
$ javac src/example/DeprecationExample.java
Note: src/example/DeprecationExample.java uses or overrides a deprecated API.
Note: Recompile with -Xlint:deprecation for details.
Use the javac -Xlint:deprecation
option to see what API is deprecated.
$ javac -Xlint:deprecation src/example/DeprecationExample.java
src/example/DeprecationExample.java:12: warning: [deprecation] getSelectedValues() in JList has been deprecated
Object[] values = jlist.getSelectedValues();
^
1 warning
Here is an example of a removal warning.
public class RemovalExample {
public static void main(String[] args) {
System.runFinalizersOnExit(true);
}
}
$ javac RemovalExample.java
RemovalExample.java:3: warning: [removal] runFinalizersOnExit(boolean) in System
has been deprecated and marked for removal
System.runFinalizersOnExit(true);
^
1 warning
==========
Suppressing Deprecation Warnings
The javac -Xlint
options control warnings for all files compiled in a particular run of javac
. You may have identified specific locations in source code that generate warnings that you no longer want to see. You can use the @SuppressWarnings
annotation to suppress warnings whenever that code is compiled. Place the @SuppressWarnings
annotation at the declaration of the class, method, field, or local variable that uses a deprecated API.
@SuppressWarnings
options are:
-
@SuppressWarnings("deprecation") — Suppresses only the ordinary deprecation warnings.
-
@SuppressWarnings("removal") — Suppresses only the removal warnings.
-
@SuppressWarnings({"deprecation","removal"}) — Suppresses both types of warnings.
Here’s an example of suppressing a warning.
@SuppressWarnings("deprecation")
Object[] values = jlist.getSelectedValues();
With the @SuppressWarnings
annotation, no warnings are issued for this line, even if warnings are enabled on the command line.
Running jdeprscan
jdeprscan
is a static analysis tool that reports on an application’s use of deprecated JDK API elements. Run jdeprscan
to help identify possible issues in compiled class files or jar files.
You can find out about deprecated JDK APIs from the compiler notifications. However, if you don’t recompile with every JDK release, or if the warnings were suppressed, or if you depend on third-party libraries that are distributed as binary artifacts, then you should run jdeprscan
.
It’s important to discover dependencies on deprecated APIs before the APIs are removed from the JDK. If the binary uses an API that is deprecated for removal in the current JDK release, and you don’t recompile, then you won’t get any notifications. When the API is removed in a future JDK release, then the binary will simply fail at runtime. jdeprscan
lets you detect such usage now, well before the API is removed.
For the complete syntax of how to run the tool and how to interpret the output, see jdeprscan
in the Java Platform, Standard Edition Tools Reference.