Java 核心基础(一)Annotation 注解

35 篇文章 11 订阅

Annotation 是 Java1.5 推出的新特性。它用来描述 Java 中的代码,如类、方法、字段等等。所以也把注解称之为元数据。

Java1.5 内置的常见的注解:

  • @Deprecated
  • @Override
  • @Deprecated

使用 Java 内置的 @Deprecated 注解,举个例子:

@Deprecated
public void test(){
    // do something
}

上面的 @Deprecated 注解使用在 Java 的方法上,表示说该方法已经废弃了,不建议使用者调用


除了 @Deprecated 注解还有 @Override,表示该方法是重写父类的方法:


public class AnnotationTest {

    @Override
    public String toString() {
        return super.toString();
    }
}

在 JDK1.5 中除了内置上面两个注解外,还有 @SuppressWarnings该注解主要用于抑制编译器警告,例如:


@SuppressWarnings("unchecked")
public void testWarning() {
    List list = new ArrayList();
    list.add("a");
    list.add("b");
    list.add("c");
}

自定义注解

在自定义注解之前,我们可以看下 JDK 内置的注解的源码,看看系统是怎么定义注解的,以 @Deprecated 为例:


@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER, TYPE})
public @interface Deprecated {

}

我们发现,Java 是通过 @interface 关键字来定义注解的。

除此以外,我们还发现,在 @Deprecated 注解上还有 @Documented、@Target、@Retention 注解,这些注解用来描述 @Deprecated 注解的,我们把它称之为元注解。

什么是元注解呢?就是描述注解的注解。什么是元数据呢?就是描述数据的数据。

@Documented 元注解

用来描述目标注解将被 javadoc 工具提取成文档。

例如在 AnnotationTest 类上使用 @Deprecated 注解:

@Deprecated
public class AnnotationTest {

}

然后使用 javadoc 命令来生成文档,然后查看生成的文档 html :

我们发现 @Deprecated 被提取到 API 文档上了。

我们可以使用 @SuppressWarnings 注解来描述 AnnotationTest:

@SuppressWarnings("unchecked")
public class AnnotationTest {

}

@SuppressWarnings 注解没有被 @Documented 元注解修饰,所以 API 文档上不会有该注解。

通过 javadoc 命令重新生成 API 文档:

@Target 元注解

描述目标注解用在哪个地方,比如:是用在方法上,还是用在类上。具体有哪些地方呢? Java 通过枚举列举出来了:

public enum ElementType {
    // 类、接口、枚举
    TYPE,

    // 字段
    FIELD,

    // 方法
    METHOD,

    // 参数
    PARAMETER,

    // 构造函数
    CONSTRUCTOR,

    // 局部变量
    LOCAL_VARIABLE,

    // 注解
    ANNOTATION_TYPE,

    // 包
    PACKAGE,
}

@Retention 元注解

用于描述目标注解保留在什么阶段。主要有三个阶段,定义在 RetentionPolicy 枚举类中:

public enum RetentionPolicy {

    // 注解只保留在源码中,编译成 class 后就不存在了
    SOURCE,

    // 注解保留在 class 字节码中,这是默认值
    CLASS,

    // 注解保留到运行时,程序运行的时候也可以获取到该注解
    RUNTIME
}

@Inherited 元注解

除了上面几个元注解,还有 @Inherited 元注解,该元注解表示目标注解具有继承性,听起来还是不好理解,下面通过例子来说明下:

首先我们自定义一个注解(该注解被 @Inherited 元注解修饰):

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface BaseAnnotation {
}

然后新建一个类 BaseClass :

@BaseAnnotation
class BaseClass {

}

然后再新建一个类,然后继承上面的 BaseClass :

public class InheritedTest extends BaseClass {
    public static void main(String[] args) {
        // InheritedTest 有没有被 BaseAnnotation 注解修饰?
        System.out.println(InheritedTest.class.isAnnotationPresent(BaseAnnotation.class));
    }
}

上面的程序输出 true。

虽然我们的 InheritedTest 类并没有显式的被 BaseAnnotation 修饰,但是它的父类 BaseClass 被 BaseAnnotation 注解修饰了,又因为 BaseAnnotation 注解被元注解 @Inherited 修饰,所以具备继承性。InheritedTest 继承了 BaseClass,也把 BaseAnnotation 注解继承过来了。我们可以把 @Inherited 注解去掉,在运行程序,会输出 false,因为这个时候 BaseAnnotation 没有继承性了。

 

注解与反射

关于注解与反射相关的内容可以查看我的博客:《Java 核心基础(二)反射技术详解》

 


 

  • 6
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Chiclaim

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值