JDK-8145716 : 9.6.4.6: Clarify relationship of "enhanced" deprecation to traditional deprecation
  • Type: Sub-task
  • Component: specification
  • Sub-Component: language
  • Affected Version: 8
  • Priority: P4
  • Status: Closed
  • Resolution: Fixed
  • Submitted: 2015-12-17
  • Updated: 2018-08-03
  • Resolved: 2016-11-18
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 9
9Fixed
Description
The @Deprecated annotation is covered in JLS 9.6.4.6:

http://docs.oracle.com/javase/specs/jls/se8/html/jls-9.html#jls-9.6.4.6

Of particular note is the change proposed by JDK-8145471 to add a new "lint" category to handle warnings about for-removal deprecations. This JLS section mentions only @SuppressWarnings("deprecation"). It would need to be updated to mention this new category, or at least to allow for the possibility of a different string being necessary here.
Comments
JEP 277 text has been updated to cover "(ordinary) deprecation warnings" and "removal warnings" and suppression thereof. This addresses comments from Alex raised on 2016-06-29 though somewhat differently from what was suggested there.
01-11-2016

Updated text for 9.6.4.5: If a program declaration is annotated with the annotation @SuppressWarnings(value = {S1, ..., Sk}), then a Java compiler must not report any warning identified by one of S1 ... Sk if that warning would have been generated as a result of the annotated declaration or any of its parts. ***The following kinds of warnings are produced according to the rules of the Java Programming Language, and may be identified for suppression using a standard name:*** - Unchecked warnings ***(4.8, 5.1.9, 5.5.2, 8.4.1, 8.4.8.3, 15.13.2, 15.27.3), identified*** by the string "unchecked" - ***Ordinary deprecation warnings (9.6.4.6), identified by the string "deprecation"*** - ***Terminal deprecation warnings (9.6.4.6), identified by the string "removal"*** [Note:] ***For other kinds of warnings,*** compiler vendors should document the warning names they support in conjunction with this annotation type. Vendors are encouraged to cooperate to ensure that the same names work across multiple compilers.
29-09-2016

Edited the spec text: - Framed the section in terms of "the annotation type 'Deprecated'" rather than the @Deprecated annotation - Defined "ordinarily deprecated" and "terminally deprecated", and made subsequent use of these terms
29-09-2016

Change for 9.6.4.6 text, based on the current JEP 277 description: ***Programmers are sometimes*** discouraged from using ***certain program elements,*** typically because ***they are*** dangerous, or because a better alternative exists. ***The annotation type 'Deprecated' allows a compiler to warn about uses of these program elements.*** ***A type, method, field, or constructor annotated with a @Deprecated annotation is _deprecated_. There are two kinds of deprecation, depending on the value of the 'forRemoval' element of the annotation. An _ordinarily deprecated_ program element is indicated with 'forRemoval=false' (the default), while a _terminally deprecated_ program element is indicated with 'forRemoval=true'. ***A terminally deprecated program element is intended to be removed in a future release of the API, and programmers should stop using it or risk binary and source incompatibilities (Chapter 13) when upgrading to a newer release of the API.*** A Java compiler must produce ***an ordinary*** deprecation warning when ***an ordinarily deprecated*** type, method, field, or constructor ***is used*** (overridden, invoked, or referenced by name) in a construct which is explicitly or implicitly declared, unless: ��� The use is within an entity that is itself ***deprecated, either ordinarily or terminally***; or ��� The use is within an entity that is annotated to suppress the warning with ***a*** @SuppressWarnings ***annotation whose 'value' element contains the string "deprecation"***; or ��� The use and declaration are both within the same outermost class. ***A Java compiler must produce a terminal deprecation warning when a terminally deprecated type, method, field, or constructor is used (overridden, invoked, or referenced by name) in a construct which is explicitly or implicitly declared, unless***: ��� ***The use is within an entity that is annotated to suppress the warning with a @SuppressWarnings annotation whose 'value' element contains the string "removal"; or*** ��� ***The use and declaration are both within the same outermost class.*** ***[Note:] Terminal deprecation warnings are sufficiently urgent that a usage appearing in another deprecated entity will still receive a warning (unless exempted for another reason). This is true even when the use-site entity is _also_ terminally deprecated, since there is no guarantee that both entities will be removed at the same time. To dismiss the warning but continue using the entity, the programmer must manually acknowledge the risk via a @SuppressWarnings annotation.*** Use of the @Deprecated annotation on a local variable declaration or on a parameter declaration has no effect.
29-09-2016

Specification might be simplified by defining terms like "deprecated entity" and "terminally deprecated entity", and then referencing those definitions in the (long) sentences introducing the bulleted lists of exceptions. I avoided this, though, since it's not clear the simplification outweighs the cost of introducing new terminology.
21-09-2016

Design issues to be addressed by the JEP include: - If a declaration is annotated with the "enhanced" @Deprecated(forRemoval=true), then does the Java language mandate a "traditional" deprecation warning at use sites, or a new and more muscular kind of warning? The answer is the latter if @SuppressWarnings("deprecation") can't suppress the warning. In that case, a soft form of source incompatibility arises where a use site has @SuppressWarnings("deprecation") and the declaration site evolves from @Deprecated to @Deprecated(forRemoval=true) -- recompiling the use site will produce a warning where none previously occurred. This could be significant if invoking javac -Werror. - If a declaration is annotated with @Deprecated(forRemoval=true), then is a warning due for a use site annotated with @Deprecated / @Deprecated(forRemoval=false) ? Tradition suggests not, since in SE 8 a deprecated method can call a deprecated method without warning. However, the muscular nature of "enhanced" deprecation suggests that calling a @Deprecated(forRemoval=true) method is a really bad idea even if the caller is @Deprecated; and that the warning should be off only if the caller is also @Deprecated(forRemoval=true).
30-06-2016