Saturday, August 27, 2016

Applying JDK 9 @Deprecated Enhancements

I discussed the currently proposed JDK 9 enhancements for the @Deprecated annotation in the blog post JDK 9 @Deprecated Annotation Enhancements. In this post, I look in greater detail at the recommended usage of these minor enhancements and demonstrate how key Java SE APIs are already having these @Deprecated enhancements applied.

The current version of the main JEP 277 ("Enhanced Deprecation") web page states, "The primary purpose of enhancing the @Deprecated annotation is to provide finer-grained information to tools about the deprecation status of an API." The page also describes the two new methods being added to the @Deprecated annotation [forRemoval() and since()]:

  • "A method forRemoval() returning a boolean. If true, it means that this API element is earmarked for removal in a future release. If false, the API element is deprecated, but there is currently no intention to remove it in a future release. The default value of this element is false. ... The forRemoval() boolean element, if true, indicates intent that the API element is to be removed in some future release of the project. Users of the API are thus given advance warning that, if they don't migrate away from the API, their code is liable to break when upgrading to a newer release. If forRemoval() is false, this indicates a recommendation to migrate away from the deprecated API, but without any specific intent to remove that API."
  • "A method named since() returning String. This string should contain the release or version number at which this API became deprecated. It has free-form syntax, but the release numbering should follow the same scheme as the @since Javadoc tag for the project containing the deprecated API. ... The default value of this element is the empty string."

This text makes it clear that the intention is to be able to explicitly state whether a deprecated element is likely (planned) to be removed or if there are no plans to remove the deprecated element. This can be important information for clients of that deprecated element to know with what urgency they need to change their use of the deprecated element to a different element.

The application of new JDK 9 @Deprecated methods on the Java SE API can also be instructive in how they are intended to be used. About this, the JEP 277 page currently states (my emphasis added), "Several Java SE APIs will have a @Deprecated annotation added, updated, or removed. Some proposed changes are listed below. Unless otherwise specified, the deprecations listed here are not for removal. Note that this is not a comprehensive list of deprecations in Java SE 9. Also note that several of these items will not be implemented in Java SE 9." With this overview in mind, I now turn attention to examples from the current JDK 9 API documentation to illustrate these concepts.

Not Yet Deprecated

JEP 277's web page currently lists "add @Deprecated to the Optional.get method (JDK-8160606)" as one of the Java SE APIs for which "proposed changes" apply. Because deprecating Optional.get() is currently associated with a bug (JDK-8160606), it has not been ruled out for JDK 9 even though the current Javadoc documentation doesn't show it applied yet. The next two screen snapshots demonstrate that Optional.get() is not yet deprecated in Java SE 9.

Java SE 8: Optional.get() Introduced
Java SE 9: Optional.get() Not Yet Deprecated

Deprecated With No Plans for Removal

JEP 277 includes deprecation of constructors of "boxed primitives" in its list of Java SE APIs with "proposed changes" in @Deprecation handling. The next two screen snapshots demonstrate that the JDK 9 version of Boolean does have new @Deprecated annotations applied to its constructors.

Java SE 8: Boolean Constructors Not Deprecated
Java SE 9: Boolean Constructors Deprecated since=9

It's worth noting that the newly applied @Deprecated annotations include one of the new methods (since="9"), but not the other (no specification of forRemoval(). In the case, the user of Boolean should assume, unless otherwise stated, that the Boolean constructors were deprecated since Java SE 9, but that there are no current plans to remove these deprecated constructors.

The Applet classes are treated similarly to the "boxed primitive" constructors in terms of JDK 9 @Deprecated annotation. Like the constructors of the boxed primitives classes, key applet-related classes are being newly deprecated in JDK 9, have since="9" included in the annotation to make it clear that they were annotated with Java SE 9, and don't have forRemoval() specified (meaning that false is assumed). Applet deprecation is covered by JEP 289 ("Deprecate the Applet API"), which does state, "Add the @Deprecated(since="9") annotation" to selected applet-related classes.

Applet Class @Deprecated Since JDK 9 But With No forRemoval()

Deprecated and Planned for Removal

One example of something deprecated in JDK 9 and marked for removal is System.runFinalizersOnExit(boolean). The following screen snapshots indicate that this method was already deprecated in Java SE 8, but that its deprecation in Java SE 9 also communicates that there is intent to remove this method. I also like that it communicates that this method deprecated clear back in Java 1.2.

Java SE 8: Deprecated Method with No Hint at Removal Plans or Version Originally Deprecated
Java SE 9: Deprecated Method Communication Original Deprecated Version and Removal Intent

Conclusion

JEP 277 is a highly readable treatise on the current deficiencies of @Deprecated and how the minor enhancements of JDK 9 can mitigate at least a portion of those deficiencies. Although in many ways the JDK 9 changes to @Deprecated might be described as "baby steps," they do provide a little more standardized facility for communicating a particular deprecation's history and future plans than what was available before JDK 9. The section of JEP 277 called "Usage in Java SE" is interesting in its own right because it describes several Java SE APIs (only a subset of which were highlighted in this post) that have been proposed to have their deprecation status changed or have additional details about the deprecation's history and/or future plans added to it.

No comments: