Before Java9
注解@Deprecated可以标记Java API状态,表示API已过时和不被推荐使用。
标记原因可以是以下几种:
- 使用它存在某些风险,可能导致错误
- 一个更好和更高效的方案可以取代它
- 在未来版本中可能对其无法兼容地进行更改,或者在将来的版本中将其删除
使用被 @Deprecated 标记的 API 会被编译器警告,或者被IDE的语法检查做黄色的警告。
在Java9之前,有一些早期的设计不是很好的API由于已被广泛使用,不得不保留下去。顶多是有的API被标记为@Deprecated而不被推荐使用,其实没有强硬删除的意味。因为一旦真的删除某些API,可能会使得使用这些API的程序不兼容或者出现Bug,会带来很多麻烦事。但这一切都会被Java9颠覆。
而且在Java9之前,@Deprecated都是没有元素的,但Java9为我们增加了两个元素。
Since Java9Java9为注解增加了两个新元素:since 和 forRemoval。
- since: 元素指定已注解的API元素已被弃用的版本。
- forRemoval: 元素表示注解的 API 元素在将来的版本中被删除,应该迁移 API。
也就是说,对于被标记为@Deprecated的元素,不迁移该API的使用,可能在JDK版本升级后是不行的。
由于Java9引入了模块化,所以需要对模块这部分的@Deprecated做一个说明: 一个被标记@Deprecated的模块不会影响其中的部分,使用的那些部分如果没有@Deprecated修饰,就不会被编译器警告。
使用说明- 强烈建议在文档中使用@Deprecated的javadoc标记说明不赞成使用程序元素的原因。 该文档还应该建议并链接到建议的替代API(如果适用)。 替代API的语义通常会有所不同,因此也应讨论此类问题,给用户一个明确的说明。
- 建议为所有新注释的程序元素都提供一个since值。 这不是强制性的,只是建议。毕竟许多现有的注释都缺少此元素值(过去大多是Java8,而变化就是在Java8到Java9的路上开始的)。
- 注释元素之间没有定义的顺序。 按照惯用写法并参照定义样式,先写since后写forRemoval会比较好。
- 如果存在@Deprecated 的javadoc标记,则@Deprecated注释应始终存在,反之亦然。
package java.lang;
import java.lang.annotation.*;
import static java.lang.annotation.ElementType.*;
/**
* @author Neal Gafter
* @since 1.5
* @jls 9.6.4.6 @Deprecated
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, MODULE, PARAMETER, TYPE})
public @interface Deprecated {
/**
* @return the version string
* @since 9
*/
String since() default "";
/**
* @return whether the element is subject to removal
* @since 9
*/
boolean forRemoval() default false;
}
实战练习
用记事本写一下代码——DeprecatedTest.java
class Person {
private int id;
private String name;
@Deprecated(since="1.1")
Person(){}
Person(int id, String name) {
this.id = id;
this.name = name;
}
@Deprecated(since="1.1")
public void setId(int id) {
this.id = id;
}
public int getId() {
return this.id;
}
@Deprecated(since="1.1")
public void setName(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
}
public class DeprecatedTest {
public static void main(String[] args) {
Person p1 = new Person();
p1.setId(1);
p1.setName("Sam");
Person p2 = new Person(2, "Bob");
}
}
编译的时候会爆警告的:
获取一下详细信息,果然是调用我们标记@Deprecated的API的部分: